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_server_prepare_post_body_optional_attributes(self): server = Server( core_number=2, memory_amount=1024, hostname='my.example.com', zone=ZONE.Chicago, storage_devices=[ Storage( os='Ubuntu 14.04', size=10 ) ], vnc_password='******', password_delivery='email', login_user=login_user_block('upclouduser', ['this-is-a-SSH-key']), avoid_host='12345678' ) body = server.prepare_post_body() 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' 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'
def test_server_prepare_post_body(self): server = Server( core_number=2, memory_amount=1024, hostname='my.example.com', zone=ZONE.Chicago, storage_devices=[ Storage(os='Ubuntu 14.04', 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-000030040200' 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 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 __reset(self, **kwargs): """ Reset the objects attributes. Accepts servers as either unflattened or flattened UUID strings or Server objects. """ # name is required and should be stored in a hidden attribute for .save() if 'name' in kwargs: self._api_name = kwargs['name'] else: raise Exception('`name` is requred') # flatten { servers: { server: [] } } if 'servers' in kwargs and kwargs['servers'] and 'server' in kwargs[ 'servers']: servers = kwargs['servers']['server'] else: servers = kwargs['servers'] # convert UUIDs into server objects if servers and isinstance(servers[0], six.string_types): kwargs['servers'] = [ Server(uuid=server, populated=False) for server in servers ] else: kwargs['servers'] = servers for key, val in kwargs.items(): setattr(self, key, val)
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 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_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 get_servers(self, populate=False): servers = (self.read_json_data("server").get("servers").get("server") if populate else self.read_json_data( "server_populated").get("servers").get("server")) server_list = list() for server in servers: server_list.append(Server(server, cloud_manager=self)) return server_list
def get_server(self, UUID): """ Return a (populated) Server instance. """ server, IPAddresses, storages = self.get_server_data(UUID) return Server(server, ip_addresses=IPAddresses, storage_devices=storages, populated=True, cloud_manager=self)
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 create_server(self, server): """ Create a server and its storages based on a (locally created) Server object. Populates the given Server instance with the API response. 0.3.0: also supports giving the entire POST body as a dict that is directly serialised into JSON. Refer to the REST API documentation for correct format. Example: server1 = Server( core_number = 1, memory_amount = 512, hostname = "my.example.1", zone = ZONE.London, storage_devices = [ Storage(os = "Ubuntu 14.04", size=10, tier=maxiops, title='The OS drive'), Storage(size=10), Storage() title = "My Example Server" ]) manager.create_server(server1) One storage should contain an OS. Otherwise storage fields are optional. - size defaults to 10, - title defaults to hostname + " OS disk" and hostname + " storage disk id" (id is a running starting from 1) - tier defaults to maxiops - valid operating systems are: "CentOS 6.5", "CentOS 7.0" "Debian 7.8" "Ubuntu 12.04", "Ubuntu 14.04" "Windows 2003","Windows 2008" ,"Windows 2012" """ if isinstance(server, Server): body = server.prepare_post_body() else: server = Server._create_server_obj(server, cloud_manager=self) body = server.prepare_post_body() res = self.post_request('/server', body) server_to_return = server server_to_return._reset( res['server'], cloud_manager=self, populated=True ) return server_to_return
def create_server(self, server): """ Create a server and its storages based on a (locally created) Server object. Populates the given Server instance with the API response. 0.3.0: also supports giving the entire POST body as a dict that is directly serialised into JSON. Refer to the REST API documentation for correct format. Example: server1 = Server( core_number = 1, memory_amount = 512, hostname = "my.example.1", zone = ZONE.London, storage_devices = [ Storage(os = "Ubuntu 14.04", size=10, tier=maxiops, title='The OS drive'), Storage(size=10), Storage() title = "My Example Server" ]) manager.create_server(server1) One storage should contain an OS. Otherwise storage fields are optional. - size defaults to 10, - title defaults to hostname + " OS disk" and hostname + " storage disk id" (id is a running starting from 1) - tier defaults to maxiops - valid operating systems are: "CentOS 6.5", "CentOS 7.0" "Debian 7.8" "Ubuntu 12.04", "Ubuntu 14.04" "Windows 2003","Windows 2008" ,"Windows 2012" """ if isinstance(server, Server): body = server.prepare_post_body() else: server = Server._create_server_obj(server, cloud_manager=self) body = server.prepare_post_body() res = self.post_request('/server', body) server_to_return = server server_to_return._reset(res['server'], cloud_manager=self, populated=True) return server_to_return
def test_ip_in_server_details(self): """IPAddress in server details. https://www.upcloud.com/api/8-servers/#get-server-details """ ip = IPAddress(access='private', address='10.0.0.0', family='IPv4') assert ip.to_dict() == { 'access': 'private', 'address': '10.0.0.0', 'family': 'IPv4' } data = read_from_file( 'server_00798b85-efdc-41ca-8021-f6ef457b8531.json') s = Server(**json.loads(data)) for ip in s.ip_addresses: assert set(ip.to_dict().keys()) == set( ['address', 'family', 'access'])
def get_servers(self, populate=False, tags_has_one=None, tags_has_all=None): """ Return a list of (populated or unpopulated) Server instances. - populate = False (default) => 1 API request, returns unpopulated Server instances. - populate = True => Does 1 + n API requests (n = # of servers), returns populated Server instances. New in 0.3.0: the list can be filtered with tags: - tags_has_one: list of Tag objects or strings returns servers that have at least one of the given tags - tags_has_all: list of Tag objects or strings returns servers that have all of the tags """ if tags_has_all and tags_has_one: raise Exception( 'only one of (tags_has_all, tags_has_one) is allowed.') request = '/server' if tags_has_all: tags_has_all = [str(tag) for tag in tags_has_all] taglist = ':'.join(tags_has_all) request = '/server/tag/{0}'.format(taglist) if tags_has_one: tags_has_one = [str(tag) for tag in tags_has_one] taglist = ','.join(tags_has_one) request = '/server/tag/{0}'.format(taglist) servers = self.get_request(request)['servers']['server'] server_list = list() for server in servers: server_list.append(Server(server, cloud_manager=self)) if populate: for server_instance in server_list: server_instance.populate() return server_list
def _reset(self, **kwargs): """ Reset the objects attributes. Accepts servers as either unflattened or flattened UUID strings or Server objects. """ super(Tag, self)._reset(**kwargs) # backup name for changing it (look: Tag.save) self._api_name = self.name # flatten { servers: { server: [] } } if 'server' in self.servers: self.servers = kwargs['servers']['server'] # convert UUIDs into server objects if self.servers and isinstance(self.servers[0], six.string_types): self.servers = [ Server(uuid=server, populated=False) for server in self.servers ]
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
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'} ] }
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")
import upcloud_api from upcloud_api import Server, Storage, ZONE, login_user_block # EDIT manager = upcloud_api.CloudManager('USERNAME', 'PASSWORD') user_viktor = login_user_block( username='******', ssh_keys=['ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJnaM2JLvO4DWkmmSXys+jn0KhTRVkCfAAhv/1Pszs0DJTheQgOR9e3ThNCgR7CxIqZ5kXrZ+BIDtDs5IGrg9IA= szv-ecdsa'], create_password=False ) new_server_config = Server( hostname='upcloud.keszul.tk', zone=ZONE.Frankfurt, plan='2xCPU-2GB', storage_devices=[ Storage(os='Debian 8.0', size=50) ], login_user=user_viktor, # Docker + pip user_data='https://github.com/szepeviktor/debian-server-tools/raw/master/upcloud-init.sh' ) manager.authenticate() new_server = manager.create_server(new_server_config) # Print IP print(new_server.get_public_ip() + '\n')
def create_server(self, server): return Server._create_server_obj(server, cloud_manager=self)