def modify_storage(self, UUID, size, title): """ Modify a Storage object. Returns an object based on the API's response. """ body = Storage.prepare_put_body(size, title) res = self.request('PUT', '/storage/' + UUID, body) return Storage._create_storage_obj(res['storage'], cloud_manager=self)
def test_storage_prepare_post_body_optional_attributes(self, manager): s2 = Storage(size=100, address='virtio:0') body2 = s2.to_dict() assert body2['tier'] == 'maxiops' assert body2['size'] == 100 assert body2['address'] == 'virtio:0'
def test_server_prepare_post_body(self): server = Server( core_number=2, memory_amount=1024, hostname='my.example.com', zone='us-chi1', storage_devices=[ Storage(os='01000000-0000-4000-8000-000030200200', size=10), Storage() ] ) body = server.prepare_post_body() s1 = body['server']['storage_devices']['storage_device'][0] assert s1['title'] == 'my.example.com OS disk' assert s1['tier'] == 'maxiops' assert s1['size'] == 10 assert s1['storage'] == '01000000-0000-4000-8000-000030200200' assert s1['action'] == 'clone' s2 = body['server']['storage_devices']['storage_device'][1] assert s2['title'] == 'my.example.com storage disk 1' assert s2['tier'] == 'maxiops' assert s2['action'] == 'create' assert s2['size'] == 10 assert body['server']['title'] == 'my.example.com' assert body['server']['core_number'] == 2 assert body['server']['memory_amount'] == 1024 assert body['server']['hostname'] == server.title assert body['server']['zone'] == 'us-chi1'
def test_create_server(self, manager): responses.add(responses.POST, Mock.base_url + '/server', body=Mock.read_from_file('server_create.json'), status=202, content_type='application/json') server1 = Server(core_number=2, memory_amount=1024, hostname='my.example.com', zone=ZONE.Chicago, storage_devices=[ Storage(os='Ubuntu 20.04', size=10), Storage(size=100, title='storage disk 1') ]) manager.create_server(server1) # assert correct values in response assert type(server1).__name__ == 'Server' assert server1.core_number == '2' assert server1.memory_amount == '1024' # assert ips and storages have correct types assert type(server1.storage_devices[0]).__name__ == 'Storage' assert type(server1.ip_addresses[0]).__name__ == 'IPAddress' # assert new data was populated assert server1.video_model == 'cirrus' assert server1.vnc == 'off' assert server1.vnc_password == 'aabbccdd'
def test_storage_prepare_post_body_optional_attributes(self, manager): s2 = Storage(size=100, address='virtio:0', type='disk') body2 = s2.prepare_post_body('my.example.com', 1) assert body2['title'] == 'my.example.com storage disk 1' assert body2['tier'] == 'maxiops' assert body2['action'] == 'create' assert body2['size'] == 100 assert body2['address'] == 'virtio:0' assert body2['type'] == 'disk'
def test_server_init(self, manager): server1 = Server(core_number=2, memory_amount=1024, hostname='my.example.com', zone=ZONE.Chicago, storage_devices=[ Storage(os='Ubuntu 20.04', size=10), Storage(size=100, title='storage disk 1') ]) assert server1.title == 'my.example.com' assert server1.core_number == 2 assert server1.memory_amount == 1024 assert server1.hostname == server1.title assert server1.zone == 'us-chi1'
def test_create_server_from_template(self, manager): UUID = '01215a5a-c330-4565-81ca-0e0e22eac672' def _from_template_callback(request): request_body = json.loads(request.body) storage = request_body['server']['storage_devices']['storage_device'][0] # https://www.upcloud.com/api/8-servers/#creating-from-a-template assert storage['action'] == 'clone' assert storage['storage'] == UUID return (201, {}, Mock.read_from_file('server_create.json')) responses.add_callback( responses.POST, Mock.base_url + '/server', content_type='application/json', callback=_from_template_callback ) manager.create_server( Server( core_number=2, memory_amount=1024, hostname='my.example.com', zone='us-chi1', storage_devices=[ Storage(storage=UUID, size=10), ] ) )
def create_node(self): assert self.ssh_custom_key server = self.client.create_server( Server(core_number=8, memory_amount=4096, hostname=self.get_rnd_name('node'), zone=ZONE.London, storage_devices=[Storage(os='Debian 10.0', size=40)], login_user=self.login_user)) ip = server.get_public_ip() logging.info('CREATED %s' % ip) logging.info('WAITING FOR START...') time.sleep(30) # warm up for _ in range(10): ssh_conn = SSH_Connection(host=ip, user=self.config.get('remote', 'user'), connect_kwargs=self.ssh_custom_key) try: ssh_conn.run('whoami', hide=True) except: time.sleep(5) else: break return ip
def modify_server(self, UUID, **kwargs): """ modify_server allows updating the server's updateable_fields. Note: Server's IP-addresses and Storages are managed by their own add/remove methods. """ body = dict() body['server'] = {} for arg in kwargs: if arg not in Server.updateable_fields: Exception('{0} is not an updateable field'.format(arg)) body['server'][arg] = kwargs[arg] res = self.put_request('/server/{0}'.format(UUID), body) server = res['server'] # Populate subobjects IPAddresses = IPAddress._create_ip_address_objs( server.pop('ip_addresses'), cloud_manager=self) storages = Storage._create_storage_objs(server.pop('storage_devices'), cloud_manager=self) return Server(server, ip_addresses=IPAddresses, storage_devices=storages, populated=True, cloud_manager=self)
def modify_server(self, UUID, **kwargs): """ modify_server allows updating the server's updateable_fields. Note: Server's IP-addresses and Storages are managed by their own add/remove methods. """ body = dict() body['server'] = {} for arg in kwargs: if arg not in Server.updateable_fields: Exception('{0} is not an updateable field'.format(arg)) body['server'][arg] = kwargs[arg] res = self.request('PUT', '/server/{0}'.format(UUID), body) server = res['server'] # Populate subobjects IPAddresses = IPAddress._create_ip_address_objs(server.pop('ip_addresses'), cloud_manager=self) storages = Storage._create_storage_objs(server.pop('storage_devices'), cloud_manager=self) return Server( server, ip_addresses=IPAddresses, storage_devices=storages, populated=True, cloud_manager=self )
def templatize_storage(self, storage, title): """ Creates an exact copy of an existing storage resource which can be used as a template for creating new servers. """ url = '/storage/{0}/templatize'.format(storage) body = {'storage': {'title': title}} res = self.post_request(url, body) return Storage(cloud_manager=self, **res['storage'])
def create_storage_backup(self, storage, title): """ Creates a point-in-time backup of a storage resource. """ url = '/storage/{0}/backup'.format(storage) body = {'storage': {'title': title}} res = self.post_request(url, body) return Storage(cloud_manager=self, **res['storage'])
def eject_cd_rom(self, server): """ Ejects the storage from the CD-ROM device of a server. """ url = '/server/{0}/cdrom/eject'.format(server) res = self.post_request(url) return Storage._create_storage_objs(res['server']['storage_devices'], cloud_manager=self)
def detach_storage(self, server_uuid, address): """ Detach a Storage object to a Server. Return a list of the server's storages. """ body = {'storage_device': {'address': address}} url = '/server/{0}/storage/detach'.format(server_uuid) res = self.post_request(url, body) return Storage._create_storage_objs(res['server']['storage_devices'], cloud_manager=self)
def get_storages(self, storage_type='normal'): """ Return a list of Storage objects from the API. Storage types: public, private, normal, backup, cdrom, template, favorite """ res = self.get_request('/storage/' + storage_type) return Storage._create_storage_objs(res['storages'], cloud_manager=self)
def test_storage_prepare_post_body(self, manager): s1 = Storage(os='Ubuntu 14.04', size=10) body1 = s1.prepare_post_body('my.example.com', 1) assert body1['title'] == 'my.example.com OS disk' assert body1['tier'] == 'maxiops' assert body1['size'] == 10 assert body1['storage'] == '01000000-0000-4000-8000-000030040200' assert body1['action'] == 'clone' s2 = Storage(size=100) body2 = s2.prepare_post_body('my.example.com', 1) assert body2['title'] == 'my.example.com storage disk 1' assert body2['tier'] == 'maxiops' assert body2['action'] == 'create' assert body2['size'] == 100
def load_cd_rom(self, server, address): """ Loads a storage as a CD-ROM in the CD-ROM device of a server. """ body = {'storage_device': {'storage': address}} url = '/server/{0}/cdrom/load'.format(server) res = self.post_request(url, body) return Storage._create_storage_objs(res['server']['storage_devices'], cloud_manager=self)
def clone_storage(self, storage, title, zone, tier=None): """ Clones a Storage object. Returns an object based on the API's response. """ body = {'storage': {'title': title, 'zone': zone}} if tier: body['storage']['tier'] = tier res = self.post_request('/storage/{0}/clone'.format(str(storage)), body) return Storage(cloud_manager=self, **res['storage'])
def get_server_data(self, uuid): server_data = {} servers = self.read_json_data("server_populated").get("servers").get( "server") for server in servers: if server.get("uuid") == uuid: server_data = server IPAddresses = IPAddress._create_ip_address_objs( server.pop("ip_addresses"), cloud_manager=self) storages = Storage._create_storage_objs(server.pop("storage_devices"), cloud_manager=self) return server_data, IPAddresses, storages
def create_storage(self, size=10, tier='maxiops', title='Storage disk', zone='fi-hel1'): """ Create a Storage object. Returns an object based on the API's response. """ body = dict() body['storage'] = { 'size': size, 'tier': tier, 'title': title, 'zone': zone } res = self.post_request('/storage', body) return Storage._create_storage_obj(res['storage'], cloud_manager=self)
def _handle_server_subobjs(cls, server, cloud_manager): ip_data = server.pop('ip_addresses', None) storage_data = server.pop('storage_devices', None) tags = server.pop('tags', None) if ip_data: ip_addresses = IP_address._create_ip_address_objs(ip_data, cloud_manager=cloud_manager) server['ip_addresses'] = ip_addresses if storage_data: storages = Storage._create_storage_objs(storage_data, cloud_manager=cloud_manager) server['storage_devices'] = storages if tags and 'tag' in tags: server['tags'] = tags['tag']
def test_storage_prepare_post_body(self, manager): s1 = Storage(os='01000000-0000-4000-8000-000030200200', size=10) body1 = s1.to_dict() assert body1['tier'] == 'maxiops' assert body1['size'] == 10 s2 = Storage(size=100) body2 = s2.to_dict() assert body2['tier'] == 'maxiops' assert body2['size'] == 100
def test_storage_prepare_post_body(self, manager): s1 = Storage(os='Ubuntu 20.04', size=10) body1 = s1.to_dict() assert body1['tier'] == 'maxiops' assert body1['size'] == 10 s2 = Storage(size=100) body2 = s2.to_dict() assert body2['tier'] == 'maxiops' assert body2['size'] == 100
def get_server_data(self, UUID): """ Return '/server/uuid' data in Python dict. Creates object representations of any IP-address and Storage. """ data = self.get_request('/server/{0}'.format(UUID)) server = data['server'] # Populate subobjects IPAddresses = IPAddress._create_ip_address_objs(server.pop('ip_addresses'), cloud_manager=self) storages = Storage._create_storage_objs(server.pop('storage_devices'), cloud_manager=self) return server, IPAddresses, storages
def get_server_data(self, UUID): """ Return '/server/uuid' data in Python dict. Creates object representations of any IP-address and Storage. """ data = self.get_request('/server/{0}'.format(UUID)) server = data['server'] # Populate subobjects IPAddresses = IPAddress._create_ip_address_objs( server.pop('ip_addresses'), cloud_manager=self) storages = Storage._create_storage_objs(server.pop('storage_devices'), cloud_manager=self) return server, IPAddresses, storages
def attach_storage(self, server_uuid, storage_uuid, storage_type, address): """ Attach a Storage object to a Server. Return a list of the server's storages. """ body = {'storage_device': {}} if storage_uuid: body['storage_device']['storage'] = storage_uuid if storage_type: body['storage_device']['type'] = storage_type if address: body['storage_device']['address'] = address url = '/server/{0}/storage/attach'.format(server_uuid) res = self.post_request(url, body) return Storage._create_storage_objs(res['server']['storage_devices'], cloud_manager=self)
def create_storage(self, size=10, tier='maxiops', title='Storage disk', zone='fi-hel1', backup_rule={}): """ Create a Storage object. Returns an object based on the API's response. """ body = { 'storage': { 'size': size, 'tier': tier, 'title': title, 'zone': zone, 'backup_rule': backup_rule } } res = self.post_request('/storage', body) return Storage(cloud_manager=self, **res['storage'])
def modify_storage(self, storage, size, title): """ Modify a Storage object. Returns an object based on the API's response. """ res = self._modify_storage(str(storage), size, title) return Storage(cloud_manager=self, **res['storage'])
def get_storage(self, storage): """ Return a Storage object from the API. """ res = self.get_request('/storage/' + str(storage)) return Storage(cloud_manager=self, **res['storage'])
def test_server_prepare_post_body_optional_attributes(self): server1 = Server( core_number=2, memory_amount=1024, hostname='my.example.com', zone='us-chi1', storage_devices=[ Storage( os='01000000-0000-4000-8000-000030200200', size=10 ) ], vnc_password='******', password_delivery='email', login_user=login_user_block('upclouduser', ['this-is-a-SSH-key']), avoid_host='12345678', user_data='https://my.script.com/some_script.py', ip_addresses = [ IPAddress(family='IPv4', access='public'), IPAddress(family='IPv6', access='public') ] ) server2_dict = { 'core_number':2, 'memory_amount':1024, 'hostname':'my.example.com', 'zone': 'us-chi1', 'storage_devices':[ {'os': '01000000-0000-4000-8000-000030200200', 'size': 10} ], 'vnc_password': '******', 'password_delivery': 'email', 'login_user': login_user_block('upclouduser', ['this-is-a-SSH-key']), 'avoid_host': '12345678', 'user_data': 'https://my.script.com/some_script.py', 'ip_addresses': [ {'family':'IPv4', 'access':'public'}, {'family':'IPv6', 'access':'public'} ] } server2 = Server._create_server_obj(server2_dict, cloud_manager=self) body1 = server1.prepare_post_body() body2 = server2.prepare_post_body() for body in [body1, body2]: assert body['server']['title'] == 'my.example.com' assert body['server']['core_number'] == 2 assert body['server']['memory_amount'] == 1024 assert body['server']['hostname'] == server1.title assert body['server']['zone'] == 'us-chi1' assert body['server']['vnc_password'] == 'my-passwd' assert body['server']['password_delivery'] == 'email' assert body['server']['login_user'] == { 'username': '******', 'create_password': '******', 'ssh_keys': { 'ssh_key': ['this-is-a-SSH-key'] } } assert body['server']['avoid_host'] == '12345678' assert body['server']['user_data'] == 'https://my.script.com/some_script.py' assert body['server']['ip_addresses'] == { 'ip_address': [ {'family': 'IPv4', 'access': 'public'}, {'family': 'IPv6', 'access': 'public'} ] }
def get_storage(self, UUID): """ Return a Storage object from the API. """ res = self.get_request('/storage/' + UUID) return Storage._create_storage_obj(res['storage'], cloud_manager=self)
import requests import upcloud_api from upcloud_api import Server, Storage, ZONE, login_user_block manager = upcloud_api.CloudManager('darnellapi', 'Master1960#') manager.authenticate() noofservers = 3 login_user = login_user_block( username='******', ssh_keys=['ssh-rsa AAAAB3NzaC1yc2EAA[...]ptshi44x [email protected]'], create_password=False ) for inc in range(0, noofservers): server_config = Server( title='Server'+str(inc), plan='1xCPU-1GB', hostname='server'+str(inc)+'.darnell.com', zone=ZONE.Chicago, storage_devices=[ Storage(os='CentOS 6.5', size=25), ], login_user=login_user, user_data='/createproxy.sh' ) manager.create_server(server_config) print("end of loop")
def create(vm_): ''' Create a single Upcloud VM. ''' name = vm_['name'] try: # Check for required profile parameters before sending any API calls. if vm_['profile'] and config.is_profile_configured( __opts__, __active_provider_name__ or 'upcloud', vm_['profile'], vm_=vm_) is False: return False except AttributeError: pass if _validate_name(name) is False: return False __utils__['cloud.fire_event']( 'event', 'starting create', 'salt/cloud/{0}/creating'.format(name), args=_filter_event('creating', vm_, ['name', 'profile', 'provider', 'driver']), sock_dir=__opts__['sock_dir'], transport=__opts__['transport']) log.info('Creating Cloud VM {0}'.format(name)) root_login_user = login_user_block(username='******', ssh_keys=[get_pub_key(vm_)], create_password=False) server_kwargs = {} manager = _get_manager(vm_) location = vm_.get('location') ## TO-DO: Add support for cloning image = vm_.get('image', DEFAULT_IMAGE) extra_storage = vm_.get('extra_storage', []) storage = [ # Primary, holds the operating system Storage(uuid=image) ] + [Storage(size=s) for s in extra_storage] size_dict = _parse_size(vm_.get('size', DEFAULT_SIZE)) server_kwargs.update(size_dict) # Let's take care of any network configuration ip_addresses = vm_.get('ip_addresses', []) control_from_inside = vm_.get('control_from_inside', False) server_kwargs['zone'] = location server_kwargs['hostname'] = vm_.get('hostname', name) server_kwargs['storage_devices'] = storage server_kwargs['ip_addresses'] = ip_addresses report_data = copy.deepcopy(server_kwargs) report_data['storage_devices'] = extra_storage server_obj = Server(**server_kwargs) __utils__['cloud.fire_event']( 'event', 'requesting instance', 'salt/cloud/{0}/requesting'.format(name), args=_filter_event('requesting', report_data, ['name', 'profile', 'provider', 'driver']), sock_dir=__opts__['sock_dir'], transport=__opts__['transport']) log.debug('vm_kwargs: {0}'.format(server_kwargs)) create_server_result = manager.create_server(server_obj) log.info('create_server_result: {0}'.format(create_server_result.__dict__)) # Let's create some information worth logging out from this if create_server_result is not None and isinstance( create_server_result, Server) and create_server_result.populated: # Keep this around, we are going to need it soon enough new_server_info = create_server_result.to_dict() log.debug('create_server_result/new_server_info: {0}', new_server_info) # Will need this soon enough username = create_server_result.username password = create_server_result.password control_ip = _select_control_ip(create_server_result.ip_addresses, control_from_inside) if control_ip is None: log.error( "Could not use any of the addresses in {0} for ssh control". format(new_server_info['ip_addresses'])) return False vm_['ssh_host'] = control_ip.address vm_['password'] = password vm_['ssh_username'] = username ret = __utils__['cloud.bootstrap'](vm_, __opts__) ret.update(new_server_info) # TO-DO: insert code here to attach volumes, and other configuration steps. # # check salt/cloud/clouds/mazure.py for inspiration __utils__['cloud.fire_event']('event', 'created instance', 'salt/cloud/{0}/created'.format( vm_['name']), args=_filter_event( **{ 'name': vm_['name'], 'profile': vm_['profile'], 'provider': vm_['driver'], }), sock_dir=__opts__['sock_dir'], transport=__opts__['transport']) return ret else: log.error("Could not create Upcloud server, error: {0}".format( str(create_server_result))) return False
from __future__ import division from __future__ import absolute_import from upcloud_api import CloudManager, Storage, FirewallRule, Tag, IPAddress from upcloud_api.server import Server, login_user_block CLUSTER = { 'web1': Server( core_number=1, memory_amount=1024, hostname='web1.example.com', zone='uk-lon1', password_delivery='none', storage_devices=[ Storage(os='01000000-0000-4000-8000-000030060200', size=10), Storage(size=10, tier='maxiops') ]), 'web2': Server( core_number=1, memory_amount=1024, hostname='web2.example.com', zone='uk-lon1', password_delivery='none', storage_devices=[ Storage(os='01000000-0000-4000-8000-000030060200', size=10), Storage(size=10, tier='maxiops'), ], ip_addresses=[ IPAddress(family='IPv6', access='public')