class TestSnapshot(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 volume volume = Volume(**self.resource['volume']) self.volume = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=volume) self.client.wait_for_completion(self.volume) # Create test volume1 volume1 = Volume(**self.resource['volume']) self.volume1 = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=volume1) self.client.wait_for_completion(self.volume1) # Create test snapshot snapshot = Snapshot(**self.resource['snapshot']) self.snapshot1 = self.client.create_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], name=snapshot.name, description=snapshot.description) self.client.wait_for_completion(self.snapshot1) # Create test snapshot2 self.snapshot2 = self.client.create_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], name="python sdk test snapshot", description="snapshot test description") self.client.wait_for_completion(self.snapshot2) @classmethod def tearDownClass(self): self.client.delete_snapshot(snapshot_id=self.snapshot1['id']) self.client.delete_datacenter(datacenter_id=self.datacenter['id']) def test_list_snapshots(self): snapshots = self.client.list_snapshots() self.assertGreater(len(snapshots['items']), 0) self.assertEqual(snapshots['items'][0]['type'], 'snapshot') def test_get_snapshot(self): snapshot = self.client.get_snapshot(snapshot_id=self.snapshot1['id']) self.assertEqual(snapshot['type'], 'snapshot') self.assertEqual(snapshot['id'], self.snapshot1['id']) self.assertEqual(snapshot['properties']['name'], self.resource['snapshot']['name']) self.assertTrue(snapshot['properties']['description'], self.resource['snapshot']['description']) self.assertEqual(snapshot['properties']['location'], configuration.LOCATION) self.assertEqual(snapshot['properties']['size'], self.volume['properties']['size']) self.assertEqual(snapshot['properties']['cpuHotPlug'], self.volume['properties']['cpuHotPlug']) self.assertEqual(snapshot['properties']['cpuHotUnplug'], self.volume['properties']['cpuHotUnplug']) self.assertEqual(snapshot['properties']['ramHotPlug'], self.volume['properties']['ramHotPlug']) self.assertEqual(snapshot['properties']['ramHotUnplug'], self.volume['properties']['ramHotUnplug']) self.assertEqual(snapshot['properties']['nicHotPlug'], self.volume['properties']['nicHotPlug']) self.assertEqual(snapshot['properties']['nicHotUnplug'], self.volume['properties']['nicHotUnplug']) self.assertEqual(snapshot['properties']['discVirtioHotPlug'], self.volume['properties']['discVirtioHotPlug']) self.assertEqual(snapshot['properties']['discVirtioHotUnplug'], self.volume['properties']['discVirtioHotUnplug']) self.assertEqual(snapshot['properties']['discScsiHotPlug'], self.volume['properties']['discScsiHotPlug']) self.assertEqual(snapshot['properties']['discScsiHotUnplug'], self.volume['properties']['discScsiHotUnplug']) self.assertEqual(snapshot['properties']['licenceType'], self.volume['properties']['licenceType']) def test_delete_snapshot(self): snapshot = self.client.delete_snapshot( snapshot_id=self.snapshot2['id']) self.assertTrue(snapshot) def test_update_snapshot(self): snapshot = self.client.update_snapshot( snapshot_id=self.snapshot1['id'], name=self.resource['snapshot']['name'] + ' - RENAME', description=self.resource['snapshot']['description'] + ' - RENAME') self.client.wait_for_completion(snapshot) self.assertEqual(snapshot['type'], 'snapshot') self.assertEqual(snapshot['properties']['name'], self.resource['snapshot']['name'] + ' - RENAME') self.assertEqual( snapshot['properties']['description'], self.resource['snapshot']['description'] + ' - RENAME') def test_create_snapshot(self): self.assertEqual(self.snapshot1['type'], 'snapshot') self.assertEqual(self.snapshot1['properties']['name'], self.resource['snapshot']['name']) self.assertEqual(self.snapshot1['properties']['description'], self.resource['snapshot']['description']) def test_get_failure(self): try: self.client.get_snapshot('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_snapshot( datacenter_id='00000000-0000-0000-0000-000000000000', volume_id=self.volume['id'], name=self.resource['snapshot']['name']) except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message'])
""" from profitbricks.client import ProfitBricksService, Volume datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022' client = ProfitBricksService( username='******', password='******') i = Volume( name='Explicitly created volume', size=56, image='<IMAGE/SNAPSHOT-ID>', bus='VIRTIO') response = client.create_volume( datacenter_id=datacenter_id, volume=i) """Create snapshot """ from profitbricks.client import ProfitBricksService # noqa datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022' volume_id = '700e1cab-99b2-4c30-ba8c-1d273ddba025' client = ProfitBricksService( username='******', password='******') volume = client.create_snapshot( datacenter_id=datacenter_id, volume_id=volume_id,
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'])) wait_for_completion(self.client, self.datacenter, 'create_datacenter') # Create test volume1. self.volume1 = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=Volume(**self.resource['volume'])) wait_for_completion(self.client, self.volume1, 'create_volume') # Create test volume2 (attach volume test). self.volume2 = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=Volume(**self.resource['volume'])) wait_for_completion(self.client, self.volume2, 'create_volume') # Create test server. server = Server(**self.resource['server']) server.attach_volumes = [self.volume1['id']] self.server = self.client.create_server( datacenter_id=self.datacenter['id'], server=server) wait_for_completion(self.client, self.server, 'create_server') # Create test NIC. self.nic = self.client.create_nic( datacenter_id=self.datacenter['id'], server_id=self.server['id'], nic=NIC(**self.resource['nic'])) wait_for_completion(self.client, self.nic, 'create_nic') # Find an Ubuntu image for testing. for item in self.client.list_images()['items']: if 'Ubuntu-15' in item['properties']['name'] and item['properties']['location'] == configuration.LOCATION: self.image = item @classmethod def tearDownClass(self): self.client.delete_datacenter(datacenter_id=self.datacenter['id']) def test_list(self): servers = self.client.list_servers(datacenter_id=self.datacenter['id']) self.assertGreater(len(servers), 0) self.assertEqual(servers['items'][0]['type'], 'server') assertRegex(self, servers['items'][0]['id'], self.resource['uuid_match']) def test_get(self): server = self.client.get_server( datacenter_id=self.datacenter['id'], server_id=self.server['id'] ) self.assertEqual(server['type'], 'server') self.assertEqual(server['id'], self.server['id']) self.assertEqual(server['properties']['name'], self.resource['server']['name']) self.assertEqual(server['properties']['cores'], self.resource['server']['cores']) self.assertEqual(server['properties']['ram'], self.resource['server']['ram']) def test_delete(self): server = self.client.create_server( datacenter_id=self.datacenter['id'], server=Server(**self.resource['server']) ) wait_for_completion(self.client, server, 'create_server') response = self.client.delete_server( datacenter_id=self.datacenter['id'], server_id=server['id'] ) self.assertTrue(response) def test_update(self): server = self.client.update_server( datacenter_id=self.datacenter['id'], server_id=self.server['id'], name=self.resource['server']['name'] + ' RENAME') wait_for_completion(self.client, server, 'update_server') server = self.client.get_server( datacenter_id=self.datacenter['id'], server_id=self.server['id'] ) self.assertEqual(server['id'], self.server['id']) self.assertEqual(server['properties']['name'], self.resource['server']['name'] + ' RENAME') self.assertEqual(server['properties']['cores'], self.resource['server']['cores']) self.assertEqual(server['properties']['ram'], self.resource['server']['ram']) def test_create_simple(self): # Use server created dring server test setup assertRegex(self, self.server['id'], self.resource['uuid_match']) self.assertEqual(self.server['type'], 'server') self.assertEqual(self.server['properties']['name'], self.resource['server']['name']) self.assertEqual(self.server['properties']['cores'], self.resource['server']['cores']) self.assertEqual(self.server['properties']['ram'], self.resource['server']['ram']) self.assertIsNone(self.server['properties']['availabilityZone']) self.assertIsNone(self.server['properties']['vmState']) def test_create_complex(self): fwrule = FirewallRule(**self.resource['fwrule']) nic = NIC(firewall_rules=[fwrule], **self.resource['nic']) volume = Volume(image=self.image['id'], image_password='******', ssh_keys=['ssh-rsa AAAAB3NzaC1'], **self.resource['volume']) server = Server( nics=[nic], create_volumes=[volume], **self.resource['server']) composite_server = self.client.create_server( datacenter_id=self.datacenter['id'], server=server) wait_for_completion(self.client, composite_server, 'create_server', wait_timeout=600) composite_server = self.client.get_server( datacenter_id=self.datacenter['id'], server_id=composite_server['id']) assertRegex(self, composite_server['id'], self.resource['uuid_match']) self.assertEqual(composite_server['properties']['name'], self.resource['server']['name']) self.assertEqual(composite_server['properties']['cores'], self.resource['server']['cores']) self.assertEqual(composite_server['properties']['ram'], self.resource['server']['ram']) self.assertEqual(composite_server['properties']['availabilityZone'], 'AUTO') self.assertIn(composite_server['properties']['vmState'], self.resource['vm_states']) def test_start_server(self): server = self.client.start_server( datacenter_id=self.datacenter['id'], server_id=self.server['id']) self.assertTrue(server) def test_stop_server(self): server = self.client.stop_server( datacenter_id=self.datacenter['id'], server_id=self.server['id']) self.assertTrue(server) def test_reboot_server(self): server = self.client.reboot_server( datacenter_id=self.datacenter['id'], server_id=self.server['id']) self.assertTrue(server) def test_get_attached_volumes(self): servers = self.client.get_attached_volumes( datacenter_id=self.datacenter['id'], server_id=self.server['id']) self.assertGreater(len(servers), 0) self.assertEqual(servers['items'][0]['id'], self.volume1['id']) self.assertEqual(servers['items'][0]['properties']['name'], self.resource['volume']['name']) self.assertEqual(servers['items'][0]['properties']['size'], self.resource['volume']['size']) self.assertEqual(servers['items'][0]['properties']['bus'], self.resource['volume']['bus']) self.assertEqual(servers['items'][0]['properties']['type'], self.resource['volume']['type']) self.assertEqual(servers['items'][0]['properties']['licenceType'], 'UNKNOWN') self.assertIsNone(servers['items'][0]['properties']['image']) self.assertIsNone(servers['items'][0]['properties']['imagePassword']) self.assertFalse(servers['items'][0]['properties']['cpuHotPlug']) self.assertFalse(servers['items'][0]['properties']['cpuHotUnplug']) self.assertFalse(servers['items'][0]['properties']['ramHotPlug']) self.assertFalse(servers['items'][0]['properties']['ramHotUnplug']) self.assertFalse(servers['items'][0]['properties']['nicHotPlug']) self.assertFalse(servers['items'][0]['properties']['nicHotUnplug']) self.assertFalse(servers['items'][0]['properties']['discVirtioHotPlug']) self.assertFalse(servers['items'][0]['properties']['discVirtioHotUnplug']) self.assertFalse(servers['items'][0]['properties']['discScsiHotPlug']) self.assertFalse(servers['items'][0]['properties']['discScsiHotUnplug']) def test_get_attached_volume(self): server = self.client.get_attached_volume( datacenter_id=self.datacenter['id'], server_id=self.server['id'], volume_id=self.volume1['id']) self.assertEqual(server['id'], self.volume1['id']) self.assertEqual(server['properties']['name'], self.resource['volume']['name']) self.assertEqual(server['properties']['size'], self.resource['volume']['size']) self.assertEqual(server['properties']['bus'], self.resource['volume']['bus']) self.assertEqual(server['properties']['type'], self.resource['volume']['type']) self.assertEqual(server['properties']['licenceType'], self.resource['volume']['licence_type']) self.assertIsNone(server['properties']['image']) self.assertIsNone(server['properties']['imagePassword']) self.assertFalse(server['properties']['cpuHotPlug']) self.assertFalse(server['properties']['cpuHotUnplug']) self.assertFalse(server['properties']['ramHotPlug']) self.assertFalse(server['properties']['ramHotUnplug']) self.assertFalse(server['properties']['nicHotPlug']) self.assertFalse(server['properties']['nicHotUnplug']) self.assertFalse(server['properties']['discVirtioHotPlug']) self.assertFalse(server['properties']['discVirtioHotUnplug']) self.assertFalse(server['properties']['discScsiHotPlug']) self.assertFalse(server['properties']['discScsiHotUnplug']) def test_attach_volume(self): volume = self.client.attach_volume( datacenter_id=self.datacenter['id'], server_id=self.server['id'], volume_id=self.volume2['id']) wait_for_completion(self.client, volume, 'attach_volume') self.assertEqual(volume['id'], self.volume2['id']) self.assertEqual(volume['properties']['name'], self.resource['volume']['name']) self.assertEqual(volume['properties']['size'], self.resource['volume']['size']) self.assertEqual(volume['properties']['type'], self.resource['volume']['type']) self.assertEqual(volume['properties']['licenceType'], self.resource['volume']['licence_type']) self.assertIsNone(volume['properties']['bus']) self.assertIsNone(volume['properties']['image']) self.assertIsNone(volume['properties']['imagePassword']) self.assertFalse(volume['properties']['cpuHotPlug']) self.assertFalse(volume['properties']['cpuHotUnplug']) self.assertFalse(volume['properties']['ramHotPlug']) self.assertFalse(volume['properties']['ramHotUnplug']) self.assertFalse(volume['properties']['nicHotPlug']) self.assertFalse(volume['properties']['nicHotUnplug']) self.assertFalse(volume['properties']['discVirtioHotPlug']) self.assertFalse(volume['properties']['discVirtioHotUnplug']) self.assertFalse(volume['properties']['discScsiHotPlug']) self.assertFalse(volume['properties']['discScsiHotUnplug']) response = self.client.detach_volume( datacenter_id=self.datacenter['id'], server_id=self.server['id'], volume_id=self.volume2['id']) def test_detach_volume(self): volume = self.client.detach_volume( datacenter_id=self.datacenter['id'], server_id=self.server['id'], volume_id=self.volume1['id']) self.assertTrue(volume)
class TestUserManagement(unittest.TestCase): @classmethod def setUpClass(self): self.resource = resource() self.client = ProfitBricksService(username=configuration.USERNAME, password=configuration.PASSWORD, headers=configuration.HEADERS) # Create datacenter resource self.datacenter = self.client.create_datacenter(datacenter=Datacenter( **self.resource['datacenter'])) self.client.wait_for_completion(self.datacenter) # Create volume resource volume = Volume(**self.resource['volume']) self.volume = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=volume) self.client.wait_for_completion(self.volume) self.image = find_image(self.client, configuration.IMAGE_NAME) # Create snapshot resource self.snapshot = self.client.create_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], name=self.resource['snapshot']['name']) self.client.wait_for_completion(self.snapshot) # Reserve IP block resource self.ipblock = self.client.reserve_ipblock( IPBlock(**self.resource['ipblock'])) # Create User 1 self.user_dict1 = User( firstname='John', lastname='Doe', email='*****@*****.**' % randint(0, 9999999999999), password='******' % randint(0, 99999999), administrator=True, force_sec_auth=False) self.user1 = self.client.create_user(user=self.user_dict1) # Create User 2 self.user_dict2 = User( firstname='John', lastname='Doe', email='*****@*****.**' % randint(0, 9999999999999), password='******' % randint(0, 99999999)) self.user2 = self.client.create_user(user=self.user_dict2) # Create User 3 self.user_dict3 = User( firstname='John', lastname='Doe', email='*****@*****.**' % randint(0, 9999999999999), password='******' % randint(0, 99999999)) self.user3 = self.client.create_user(user=self.user_dict3) # Create Group 1 group = Group(**self.resource['group']) self.group1 = self.client.create_group(group) # Create Group 2 group.name = self.resource['group']['name'] + ' 2' self.group2 = self.client.create_group(group) # Create Group 3 group.name = self.resource['group']['name'] + ' 3' self.group3 = self.client.create_group(group) # Create Share 1 self.share1 = self.client.add_share(group_id=self.group3['id'], resource_id=self.datacenter['id'], edit_privilege=True, share_privilege=True) @classmethod def tearDownClass(self): self.client.delete_share(group_id=self.group3['id'], resource_id=self.datacenter['id']) self.client.delete_snapshot(snapshot_id=self.snapshot['id']) self.client.delete_user(user_id=self.user1['id']) self.client.delete_user(user_id=self.user3['id']) self.client.delete_group(group_id=self.group1['id']) self.client.delete_group(group_id=self.group3['id']) self.client.delete_ipblock(ipblock_id=self.ipblock['id']) self.client.delete_datacenter(datacenter_id=self.datacenter['id']) def test_create_user(self): self.assertEqual(self.user1['type'], 'user') self.assertEqual(self.user1['properties']['firstname'], self.user_dict1.firstname) self.assertEqual(self.user1['properties']['lastname'], self.user_dict1.lastname) self.assertEqual(self.user1['properties']['email'], self.user_dict1.email) self.assertEqual(self.user1['properties']['administrator'], self.user_dict1.administrator) self.assertEqual(self.user1['properties']['forceSecAuth'], self.user_dict1.force_sec_auth) def test_list_users(self): users = self.client.list_users() self.assertGreater(len(users['items']), 0) self.assertEqual(users['items'][0]['type'], 'user') def test_get_user(self): user = self.client.get_user(user_id=self.user1['id']) self.assertEqual(user['type'], 'user') self.assertEqual(user['id'], self.user1['id']) self.assertEqual(user['properties']['firstname'], self.user1['properties']['firstname']) self.assertEqual(user['properties']['lastname'], self.user1['properties']['lastname']) self.assertEqual(user['properties']['email'], self.user1['properties']['email']) self.assertEqual(user['properties']['administrator'], self.user1['properties']['administrator']) self.assertEqual(user['properties']['forceSecAuth'], self.user1['properties']['forceSecAuth']) self.assertFalse(user['properties']['secAuthActive']) def test_delete_user(self): user = self.client.delete_user(user_id=self.user2['id']) self.assertTrue(user) def test_update_user(self): user = self.client.update_user( user_id=self.user1['id'], firstname=self.user1['properties']['firstname'], lastname=self.user1['properties']['lastname'], email=self.user1['properties']['email'], administrator=False, force_sec_auth=self.user1['properties']['forceSecAuth']) self.assertEqual(user['type'], 'user') self.assertEqual(user['id'], self.user1['id']) self.assertEqual(user['properties']['firstname'], self.user1['properties']['firstname']) self.assertEqual(user['properties']['lastname'], self.user1['properties']['lastname']) self.assertEqual(user['properties']['email'], self.user1['properties']['email']) self.assertFalse(user['properties']['administrator']) self.assertEqual(user['properties']['forceSecAuth'], self.user1['properties']['forceSecAuth']) def test_create_user_failure(self): try: user = User(firstname='John', lastname='Doe', password='******') self.client.create_user(user) except PBError as e: self.assertIn(self.resource['missing_attribute_error'] % 'email', e.content[0]['message']) def test_get_user_failure(self): try: self.client.get_user('00000000-0000-0000-0000-000000000000') except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message']) def test_create_group(self): self.assertEqual(self.group1['type'], 'group') self.assertEqual(self.group1['properties']['name'], self.resource['group']['name']) self.assertEqual(self.group1['properties']['createDataCenter'], self.resource['group']['create_datacenter']) self.assertEqual(self.group1['properties']['createSnapshot'], self.resource['group']['create_snapshot']) self.assertEqual(self.group1['properties']['reserveIp'], self.resource['group']['reserve_ip']) self.assertEqual(self.group1['properties']['accessActivityLog'], self.resource['group']['access_activity_log']) def test_list_groups(self): groups = self.client.list_groups() self.assertGreater(len(groups['items']), 0) self.assertEqual(groups['items'][0]['type'], 'group') def test_get_group(self): group = self.client.get_group(group_id=self.group1['id']) self.assertEqual(group['type'], 'group') self.assertEqual(group['id'], self.group1['id']) self.assertEqual(group['properties']['name'], self.group1['properties']['name']) self.assertEqual(group['properties']['createDataCenter'], self.group1['properties']['createDataCenter']) self.assertEqual(group['properties']['createSnapshot'], self.group1['properties']['createSnapshot']) self.assertEqual(group['properties']['reserveIp'], self.group1['properties']['reserveIp']) self.assertEqual(group['properties']['accessActivityLog'], self.group1['properties']['accessActivityLog']) def test_update_group(self): group = self.client.update_group(group_id=self.group1['id'], name=self.resource['group']['name'] + ' - RENAME', create_datacenter=False) self.assertEqual(group['type'], 'group') self.assertEqual(group['id'], self.group1['id']) self.assertEqual(group['properties']['name'], self.resource['group']['name'] + ' - RENAME') self.assertFalse(group['properties']['createDataCenter']) def test_delete_group(self): group = self.client.delete_group(group_id=self.group2['id']) self.assertTrue(group) def test_create_group_failure(self): try: self.client.create_group(Group(create_datacenter=True)) except PBError as e: self.assertIn(self.resource['missing_attribute_error'] % 'name', e.content[0]['message']) def test_get_group_failure(self): try: self.client.get_group('00000000-0000-0000-0000-000000000000') except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message']) def test_add_share(self): self.assertEqual(self.share1['type'], 'resource') self.assertTrue(self.share1['properties']['editPrivilege']) self.assertTrue(self.share1['properties']['sharePrivilege']) def test_list_shares(self): shares = self.client.list_shares(group_id=self.group3['id']) self.assertGreater(len(shares['items']), 0) self.assertEqual(shares['items'][0]['type'], 'resource') def test_get_share(self): share = self.client.get_share(group_id=self.group3['id'], resource_id=self.datacenter['id']) self.assertEqual(share['id'], self.datacenter['id']) self.assertEqual(share['type'], 'resource') self.assertTrue(share['properties']['editPrivilege']) self.assertTrue(share['properties']['sharePrivilege']) def test_update_share(self): share = self.client.update_share(group_id=self.group3['id'], resource_id=self.datacenter['id'], share_privilege=False) self.assertEqual(share['id'], self.datacenter['id']) self.assertEqual(share['type'], 'resource') self.assertFalse(share['properties']['sharePrivilege']) def test_get_share_failure(self): try: self.client.get_share( group_id=self.group3['id'], resource_id='00000000-0000-0000-0000-000000000000') except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message']) def test_create_share_failure(self): try: self.client.add_share( group_id=self.group3['id'], resource_id='00000000-0000-0000-0000-000000000000') except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message']) def test_list_group_users(self): users = self.client.list_group_users(group_id=self.group3['id']) self.assertGreater(len(users['items']), 0) self.assertEqual(users['items'][0]['type'], 'user') def test_add_group_user(self): user = self.client.add_group_user(group_id=self.group3['id'], user_id=self.user3['id']) self.assertEqual(user['id'], self.user3['id']) self.assertEqual(user['type'], 'user') def test_remove_group_user(self): user = self.client.remove_group_user(group_id=self.group3['id'], user_id=self.user3['id']) self.assertTrue(user) def test_list_resources(self): resources = self.client.list_resources() self.assertGreater(len(resources['items']), 0) self.assertEqual(resources['id'], 'resources') self.assertEqual(resources['type'], 'collection') def test_list_datacenter_resources(self): resources = self.client.list_resources(resource_type='datacenter') self.assertGreater(len(resources['items']), 0) self.assertEqual(resources['id'], 'resources') self.assertEqual(resources['items'][0]['type'], 'datacenter') def test_list_image_resources(self): resources = self.client.list_resources(resource_type='image') self.assertGreater(len(resources['items']), 0) self.assertEqual(resources['id'], 'resources') self.assertEqual(resources['items'][0]['type'], 'image') def test_list_snapshot_resources(self): resources = self.client.list_resources(resource_type='snapshot') self.assertGreater(len(resources['items']), 0) self.assertEqual(resources['id'], 'resources') self.assertEqual(resources['items'][0]['type'], 'snapshot') def test_list_ipblock_resources(self): resources = self.client.list_resources(resource_type='ipblock') self.assertGreater(len(resources['items']), 0) self.assertEqual(resources['id'], 'resources') self.assertEqual(resources['items'][0]['type'], 'ipblock') def test_list_resources_failure(self): try: self.client.list_resources(resource_type='unknown') except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message']) def test_get_datacenter_resource(self): resource = self.client.get_resource(resource_type='datacenter', resource_id=self.datacenter['id']) self.assertEqual(resource['id'], self.datacenter['id']) self.assertEqual(resource['type'], 'datacenter') def test_get_image_resource(self): resource = self.client.get_resource(resource_type='image', resource_id=self.image['id']) self.assertEqual(resource['id'], self.image['id']) self.assertEqual(resource['type'], 'image') def test_get_snapshot_resource(self): resource = self.client.get_resource(resource_type='snapshot', resource_id=self.snapshot['id']) self.assertEqual(resource['id'], self.snapshot['id']) self.assertEqual(resource['type'], 'snapshot') def test_list_ipblock_resources2(self): resource = self.client.get_resource(resource_type='ipblock', resource_id=self.ipblock['id']) self.assertEqual(resource['id'], self.ipblock['id']) self.assertEqual(resource['type'], 'ipblock') def test_get_resource_failure(self): try: self.client.get_resource( resource_type='datacenter', resource_id='00000000-0000-0000-0000-000000000000') except PBNotFoundError as e: self.assertIn(self.resource['not_found_error'], e.content[0]['message'])
class TestVolume(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 volume self.volume = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=Volume(**self.resource['volume'])) wait_for_completion(self.client, self.volume, 'create_volume') # Create snapshot1 self.snapshot1 = self.client.create_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], name=self.resource['snapshot']['name'], description=self.resource['snapshot']['description']) wait_for_completion(self.client, self.snapshot1, 'create_snapshot1', wait_timeout=600) # Create snapshot2 (used in delete test) self.snapshot2 = self.client.create_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], name=self.resource['snapshot']['name'], description=self.resource['snapshot']['description']) wait_for_completion(self.client, self.snapshot2, 'create_snapshop2', wait_timeout=600) self.image = find_image(self.client, configuration.IMAGE_NAME) @classmethod def tearDownClass(self): self.client.remove_snapshot(snapshot_id=self.snapshot1['id']) self.client.delete_datacenter(datacenter_id=self.datacenter['id']) def test_list_volumes(self): volumes = self.client.list_volumes( datacenter_id=self.datacenter['id']) self.assertGreater(len(volumes), 0) assertRegex(self, volumes['items'][0]['id'], self.resource['uuid_match']) self.assertEqual(volumes['items'][0]['type'], 'volume') 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']['licenceType'], self.resource['volume']['licence_type']) self.assertEqual(volumes['items'][0]['properties']['type'], self.resource['volume']['type']) 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']) self.assertIsNone(volumes['items'][0]['properties']['bus']) def test_get_volume(self): volume = self.client.get_volume( datacenter_id=self.datacenter['id'], volume_id=self.volume['id']) self.assertEqual(volume['id'], self.volume['id']) self.assertEqual(volume['type'], 'volume') self.assertEqual(volume['properties']['name'], self.resource['volume']['name']) self.assertEqual(volume['properties']['size'], self.resource['volume']['size']) self.assertEqual(volume['properties']['licenceType'], self.resource['volume']['licence_type']) self.assertEqual(volume['properties']['type'], self.resource['volume']['type']) 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.assertIsNone(volume['properties']['bus']) def test_delete_volume(self): volume = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=Volume(**self.resource['volume'])) wait_for_completion(self.client, volume, 'create_volume') volume = self.client.delete_volume( datacenter_id=self.datacenter['id'], volume_id=volume['id']) self.assertTrue(volume) def test_update_volume(self): volume = self.client.update_volume( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], size=6, name=self.resource['volume']['name'] + ' RENAME') wait_for_completion(self.client, volume, 'update_volume') volume = self.client.get_volume( datacenter_id=self.datacenter['id'], volume_id=self.volume['id']) self.assertEqual(volume['id'], self.volume['id']) self.assertEqual(volume['properties']['name'], self.resource['volume']['name'] + ' RENAME') self.assertEqual(volume['properties']['size'], 6) def test_create_volume(self): # Use volume created during volume test setup. self.assertEqual(self.volume['properties']['name'], self.resource['volume']['name']) self.assertEqual(self.volume['properties']['bus'], self.resource['volume']['bus']) self.assertEqual(self.volume['properties']['type'], self.resource['volume']['type']) self.assertEqual(self.volume['properties']['size'], self.resource['volume']['size']) self.assertEqual(self.volume['properties']['licenceType'], self.resource['volume']['licence_type']) self.assertFalse(self.volume['properties']['cpuHotPlug']) self.assertFalse(self.volume['properties']['cpuHotUnplug']) self.assertFalse(self.volume['properties']['ramHotPlug']) self.assertFalse(self.volume['properties']['ramHotUnplug']) self.assertFalse(self.volume['properties']['nicHotPlug']) self.assertFalse(self.volume['properties']['nicHotUnplug']) self.assertFalse(self.volume['properties']['discVirtioHotPlug']) self.assertFalse(self.volume['properties']['discVirtioHotUnplug']) self.assertFalse(self.volume['properties']['discScsiHotPlug']) self.assertFalse(self.volume['properties']['discScsiHotUnplug']) def test_create_snapshot(self): # Use snapshot created during volume test setup. assertRegex(self, self.snapshot1['id'], self.resource['uuid_match']) self.assertEqual(self.snapshot1['type'], 'snapshot') self.assertEqual(self.snapshot1['properties']['name'], self.resource['snapshot']['name']) self.assertEqual(self.snapshot1['properties']['description'], self.resource['snapshot']['description']) self.assertEqual(self.snapshot1['properties']['location'], configuration.LOCATION) self.assertFalse(self.snapshot1['properties']['cpuHotPlug']) self.assertFalse(self.snapshot1['properties']['cpuHotUnplug']) self.assertFalse(self.snapshot1['properties']['ramHotPlug']) self.assertFalse(self.snapshot1['properties']['ramHotUnplug']) self.assertFalse(self.snapshot1['properties']['nicHotPlug']) self.assertFalse(self.snapshot1['properties']['nicHotUnplug']) self.assertFalse(self.snapshot1['properties']['discVirtioHotPlug']) self.assertFalse(self.snapshot1['properties']['discVirtioHotUnplug']) self.assertFalse(self.snapshot1['properties']['discScsiHotPlug']) self.assertFalse(self.snapshot1['properties']['discScsiHotUnplug']) self.assertIsNone(self.snapshot1['properties']['size']) self.assertIsNone(self.snapshot1['properties']['licenceType']) def test_restore_snapshot(self): response = self.client.restore_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], snapshot_id=self.snapshot1['id']) self.assertTrue(response) def test_remove_snapshot(self): volume = self.client.remove_snapshot(snapshot_id=self.snapshot2['id']) self.assertTrue(volume) def test_create_volume_failure(self): with self.assertRaises(Exception) as context: self.client.create_volume( datacenter_id=self.datacenter['id'], volume=Volume(image=self.image['id'], **self.resource['volume_failure'])) exception = ('(422, u\'[(root).properties.image] Passwords/SSH Keys ' 'are mandatory for public ProfitBricks Images.\')') self.assertIn(exception, str(context.exception))
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
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
""" from profitbricks.client import ProfitBricksService, Volume datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022' client = ProfitBricksService( username='******', password='******') i = Volume( name='Explicitly created volume', size=56, image='<IMAGE/SNAPSHOT-ID>', bus='VIRTIO') response = client.create_volume( datacenter_id=datacenter_id, volume=i) """Create snapshot """ from profitbricks.client import ProfitBricksService datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022' volume_id = '700e1cab-99b2-4c30-ba8c-1d273ddba025' client = ProfitBricksService( username='******', password='******') volume = client.create_snapshot( datacenter_id=datacenter_id, volume_id=volume_id,
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'])
class TestVolume(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) self.image = find_image(self.client, configuration.IMAGE_NAME) # Create test volume vol = Volume(**self.resource['volume2']) vol.image = self.image['id'] self.volume = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=vol) self.client.wait_for_completion(self.volume) # Create snapshot1 self.snapshot1 = self.client.create_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], name=self.resource['snapshot']['name'], description=self.resource['snapshot']['description']) self.client.wait_for_completion(self.snapshot1, timeout=600) @classmethod def tearDownClass(self): self.client.delete_datacenter(datacenter_id=self.datacenter['id']) def test_list_volumes(self): volumes = self.client.list_volumes( datacenter_id=self.datacenter['id']) self.assertGreater(len(volumes), 0) assertRegex(self, volumes['items'][0]['id'], self.resource['uuid_match']) self.assertEqual(volumes['items'][0]['type'], 'volume') self.assertEqual(volumes['items'][0]['properties']['name'], self.resource['volume2']['name']) self.assertEqual(volumes['items'][0]['properties']['size'], self.resource['volume2']['size']) self.assertEqual(volumes['items'][0]['properties']['type'], self.resource['volume2']['disk_type']) self.assertIsNone(volumes['items'][0]['properties']['bus']) def test_get_volume(self): volume = self.client.get_volume( datacenter_id=self.datacenter['id'], volume_id=self.volume['id']) self.assertEqual(volume['id'], self.volume['id']) self.assertEqual(volume['type'], 'volume') self.assertEqual(volume['properties']['name'], self.resource['volume2']['name']) self.assertEqual(volume['properties']['size'], self.resource['volume2']['size']) self.assertEqual(volume['properties']['licenceType'], self.image['properties']['licenceType']) self.assertEqual(volume['properties']['type'], self.resource['volume2']['disk_type']) self.assertIsNone(volume['properties']['bus']) self.assertEqual(volume['properties']['availabilityZone'], self.resource['volume2']['availability_zone']) def test_delete_volume(self): volume = self.client.create_volume( datacenter_id=self.datacenter['id'], volume=Volume(**self.resource['volume'])) self.client.wait_for_completion(volume) volume = self.client.delete_volume( datacenter_id=self.datacenter['id'], volume_id=volume['id']) self.assertTrue(volume) def test_update_volume(self): volume = self.client.update_volume( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], size=6, name=self.resource['volume2']['name'] + ' - RENAME') self.client.wait_for_completion(volume) volume = self.client.get_volume( datacenter_id=self.datacenter['id'], volume_id=self.volume['id']) self.assertEqual(volume['id'], self.volume['id']) self.assertEqual(volume['properties']['name'], self.resource['volume2']['name'] + ' - RENAME') self.assertEqual(volume['properties']['size'], 6) def test_create_volume(self): # Use volume created during volume test setup. assertRegex(self, self.volume['id'], self.resource['uuid_match']) self.assertEqual(self.volume['properties']['name'], self.resource['volume2']['name']) self.assertEqual(self.volume['properties']['bus'], self.resource['volume2']['bus']) self.assertEqual(self.volume['properties']['type'], self.resource['volume2']['disk_type']) self.assertEqual(self.volume['properties']['size'], self.resource['volume2']['size']) self.assertEqual(self.volume['properties']['sshKeys'], self.resource['volume2']['ssh_keys']) self.assertEqual(self.volume['properties']['availabilityZone'], self.resource['volume2']['availability_zone']) def test_create_snapshot(self): # Use snapshot created during volume test setup. self.assertEqual(self.snapshot1['type'], 'snapshot') self.assertEqual(self.snapshot1['properties']['name'], self.resource['snapshot']['name']) self.assertEqual(self.snapshot1['properties']['description'], self.resource['snapshot']['description']) self.assertEqual(self.snapshot1['properties']['location'], configuration.LOCATION) self.assertIsNone(self.snapshot1['properties']['size']) self.assertIsNone(self.snapshot1['properties']['licenceType']) def test_restore_snapshot(self): response = self.client.restore_snapshot( datacenter_id=self.datacenter['id'], volume_id=self.volume['id'], snapshot_id=self.snapshot1['id']) self.assertTrue(response) def test_remove_snapshot(self): volume = self.client.remove_snapshot(snapshot_id=self.snapshot1['id']) self.assertTrue(volume) def test_get_failure(self): try: self.client.get_volume( datacenter_id=self.datacenter['id'], volume_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: volume = Volume(name=self.resource['volume2']['name']) self.client.create_volume(datacenter_id=self.datacenter['id'], volume=volume) except PBError as e: self.assertIn(self.resource['missing_attribute_error'] % 'size', 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(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
class TestVolume(unittest.TestCase): def setUp(self): self.volume = ProfitBricksService( username='******', password='******') def test_list_volumes(self): volumes = self.volume.list_volumes( datacenter_id=datacenter_id) self.assertEqual(len(volumes), 4) self.assertEqual(volumes['items'][0]['id'], volume_id) self.assertEqual(volumes['items'][0]['properties']['name'], 'my boot volume for server 1') self.assertEqual(volumes['items'][0]['properties']['size'], 80) self.assertEqual(volumes['items'][0]['properties']['licenceType'], 'WINDOWS') 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']) self.assertEqual(volumes['items'][0]['properties']['bus'], 'VIRTIO') self.assertEqual(volumes['items'][0]['properties']['type'], 'HDD') def test_get_volume(self): volume = self.volume.get_volume( datacenter_id=datacenter_id, volume_id=volume_id) self.assertEqual(volume['properties']['name'], 'my boot volume for server 1') self.assertEqual(volume['properties']['size'], 80) self.assertEqual(volume['properties']['licenceType'], 'WINDOWS') 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.assertEqual(volume['properties']['bus'], 'VIRTIO') self.assertEqual(volume['properties']['type'], 'HDD') def test_delete_volume(self): volume = self.volume.delete_volume( datacenter_id=datacenter_id, volume_id=volume_id) self.assertTrue(volume) def test_update_volume(self): volume = self.volume.update_volume( datacenter_id=datacenter_id, volume_id=volume_id, size=100, name='Resized storage to 100 GB', cpu_hot_unplug=True) self.assertEqual( volume['properties']['name'], 'Resized storage to 100 GB') self.assertEqual(volume['properties']['size'], 100) def test_create_volume(self): i = Volume( name='Explicitly created volume', size=56, image='<IMAGE/SNAPSHOT-ID>', bus='VIRTIO') response = self.volume.create_volume( datacenter_id=datacenter_id, volume=i) self.assertEqual( response['properties']['name'], 'my boot volume for server 1') self.assertEqual(response['properties']['size'], 80) self.assertEqual(response['properties']['licenceType'], 'WINDOWS') self.assertFalse(response['properties']['cpuHotPlug']) self.assertFalse(response['properties']['cpuHotUnplug']) self.assertFalse(response['properties']['ramHotPlug']) self.assertFalse(response['properties']['ramHotUnplug']) self.assertFalse(response['properties']['nicHotPlug']) self.assertFalse(response['properties']['nicHotUnplug']) self.assertFalse(response['properties']['discVirtioHotPlug']) self.assertFalse(response['properties']['discVirtioHotUnplug']) self.assertFalse(response['properties']['discScsiHotPlug']) self.assertFalse(response['properties']['discScsiHotUnplug']) self.assertEqual(response['properties']['bus'], 'VIRTIO') self.assertEqual(response['properties']['type'], 'HDD') def test_create_optional_value(self): i = Volume( name='Explicitly created volume', size=56, image='<IMAGE/SNAPSHOT-ID>', bus='VIRTIO', ram_hot_plug=True, cpu_hot_unplug=True) response = self.volume.create_volume( datacenter_id=datacenter_id, volume=i) self.assertEqual( response['properties']['name'], 'my boot volume for server 1') self.assertEqual(response['properties']['size'], 80) self.assertEqual(response['properties']['licenceType'], 'WINDOWS') self.assertFalse(response['properties']['cpuHotPlug']) self.assertFalse(response['properties']['cpuHotUnplug']) self.assertFalse(response['properties']['ramHotPlug']) self.assertFalse(response['properties']['ramHotUnplug']) self.assertFalse(response['properties']['nicHotPlug']) self.assertFalse(response['properties']['nicHotUnplug']) self.assertFalse(response['properties']['discVirtioHotPlug']) self.assertFalse(response['properties']['discVirtioHotUnplug']) self.assertFalse(response['properties']['discScsiHotPlug']) self.assertFalse(response['properties']['discScsiHotUnplug']) self.assertEqual(response['properties']['bus'], 'VIRTIO') self.assertEqual(response['properties']['type'], 'HDD') def test_create_snapshot(self): volume = self.volume.create_snapshot( datacenter_id=datacenter_id, volume_id=volume_id, name='<URLENCODED_SNAPSHOT_NAME>', description='<URLENCODED_SNAPSHOT_DESCRIPTION>') self.assertEqual(volume['id'], snapshot_id) self.assertEqual( volume['properties']['name'], 'Snapshot of storage X on 12.12.12 12:12:12 - updated') self.assertEqual(volume['properties']['description'], 'description of a snapshot - updated') self.assertEqual(volume['properties']['location'], 'de/fkb') self.assertEqual(volume['properties']['size'], 28) self.assertEqual(volume['properties']['licenceType'], 'WINDOWS') 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_restore_snapshot(self): response = self.volume.restore_snapshot( datacenter_id=datacenter_id, volume_id=volume_id, snapshot_id=snapshot_id) self.assertTrue(response) def test_remove_snapshot(self): volume = self.volume.remove_snapshot(snapshot_id=snapshot_id) self.assertTrue(volume)