def POST_bootstrap(self): # Get the duration. # TODO: check when no duration is received, or an invalid duration is received. duration = int(request.params.get('duration', 0)) # Remove all data from DB. self.clear_deployment() # Setup initial configurations for each device type. BluetoothSKADevice.bootstrap() ADBSKADevice.bootstrap() # Create server keys. server_keys = credentials.ServerCredentials.create_object(app_globals.cloudlet.credentials_type, app_globals.cloudlet.data_folder) server_keys.generate_and_save_to_file() # Create RADIUS server certificate. radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file, app_globals.cloudlet.radius_certs_folder, app_globals.cloudlet.radius_eap_conf_file) radius_server.generate_certificate() # Set up a new deployment. deployment = Deployment() deployment.auth_start = datetime.datetime.now() deployment.auth_duration = duration deployment.save() # Go to the main page. return h.redirect_to(controller='devices', action='list')
def generate_migration_device_credentials(device_id, connection_id, svm_id): print 'Preparing credentials and cloudlet information.' device_credentials = PairedDeviceDataBundle() try: # Get the new credentials for the device on the current deployment. print 'Generating credentials for device that will migrate to our cloudlet.' deployment = Deployment.get_instance() device_type = 'mobile' device_keys = deployment.pair_device(device_id, connection_id, device_type) # Configure the associated instance. paired_device = PairedDevice.by_id(device_id) paired_device.instance = svm_id paired_device.save() # Bundle the credentials for a newly paired device. print 'Bundling credentials for device.' device_credentials.auth_password = device_keys.auth_password device_credentials.server_public_key = device_keys.server_public_key device_credentials.device_private_key = device_keys.private_key device_credentials.load_certificate(deployment.radius_server.cert_file_path) except DeviceAlreadyPairedException as e: print 'Credentials not generated: ' + e.message # Bundle common cloudlet information. print 'Bundling cloudlet information for device.' cloudlet = get_cloudlet_instance() device_credentials.cloudlet_name = Cloudlet.get_hostname() device_credentials.cloudlet_fqdn = Cloudlet.get_fqdn() device_credentials.cloudlet_encryption_enabled = cloudlet.api_encrypted device_credentials.ssid = cloudlet.ssid print 'Returning credentials and cloudlet data.' return device_credentials.__dict__
def GET_clear(self): deployment = Deployment.get_instance() deployment.clear() deployment.remove() # Go to the main page. return h.redirect_to(controller='devices', action='list')
def GET_list(self): c.devices_active = 'active' page = DevicesPage() # Ensure the device types are initialized. BluetoothSKADevice.initialize(app_globals.cloudlet.data_folder) ADBSKADevice.initialize(app_globals.cloudlet.data_folder) # Get the overall deployment info. page.deployment = Deployment.get_instance() if page.deployment.auth_start is None: page.deployment_auth_start = 'not set' page.deployment_auth_duration = 'not set' page.deployment_auth_end = 'not set' else: page.deployment_auth_start = page.deployment.auth_start.strftime( '%Y-%m-%d %X') page.deployment_auth_duration = page.deployment.auth_duration page.deployment_auth_end = ( page.deployment.auth_start + datetime.timedelta(minutes=page.deployment.auth_duration) ).strftime('%Y-%m-%d %X') # Get the paired devices. page.paired_devices = PairedDevice.by_type('mobile') # Get the paired cloudlets. page.paired_cloudlets = PairedDevice.by_type('cloudlet') return page.render()
def GET_authorize(self, did): connection_id = request.params.get('cid', None) auth_password = request.params.get('auth_password', None) enc_password = request.params.get('enc_password', None) # Create a new paired device with the id info we just received. print 'Adding paired device to DB.' paired_device = PairedDevice() paired_device.device_id = did paired_device.connection_id = connection_id paired_device.password = enc_password # By default, authorization for a device will be the same as the deployment info. deployment = Deployment.find_one() paired_device.auth_start = deployment.auth_start paired_device.auth_duration = deployment.auth_duration paired_device.auth_enabled = True # Store the paired device. paired_device.save() # Store the new device credentials in the RADIUS server. radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file, app_globals.cloudlet.radius_certs_folder, app_globals.cloudlet.radius_eap_conf_file) radius_server.add_user_credentials(paired_device.device_id, auth_password) # Go to the main page. print 'Device added to DB.' return ajaxutils.JSON_OK
def clear_deployment(self): # Remove users from RADIUS server. print 'Removing paired devices from RADIUS server.' devices = PairedDevice.find() device_ids = [] for device in devices: device_ids.append(device.device_id) stop_associated_instance(device.device_id) radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file, app_globals.cloudlet.radius_certs_folder, app_globals.cloudlet.radius_eap_conf_file) radius_server.remove_user_credentials(device_ids) # Remove all data from DB. print 'Clearing up database.' PairedDevice.clear_data() Deployment.remove()
def POST_bootstrap(self): # Get the duration. # TODO: check when no duration is received, or an invalid duration is received. duration = int(request.params.get('duration', 0)) # Setup initial configurations for each device type. BluetoothSKADevice.bootstrap() ADBSKADevice.bootstrap() deployment = Deployment.get_instance() deployment.bootstrap(duration) # Go to the main page. return h.redirect_to(controller='devices', action='list')
def abort_migration(svm_id): # Get the id and load the metadata for this SVM. migrated_svm = ServiceVM.by_id(svm_id, only_find_ready_ones=False) if not migrated_svm: raise SVMNotFoundException("No SVM found with the given id {}".format(svm_id)) print 'Aborting migration, cleaning up...' migrated_svm.stop() # Unpairing all paired devices that were using this VM. deployment = Deployment.get_instance() paired_devices = PairedDevice.by_instance(svm_id) for paired_device in paired_devices: deployment.unpair_device(paired_device.device_id) print 'Cleanup finished.'
def GET_pair(self, id): device_type = 'mobile' connection = request.params.get('connection', None) if connection is None: connection = 'bt' curr_device = None try: # Create a device depending on the type. if connection == 'bt': port = request.params.get('port', None) name = request.params.get('name', None) curr_device = BluetoothSKADevice({ 'host': id, 'port': int(port), 'name': name }) else: curr_device = ADBSKADevice(id) # Now the pairing process will be followed, generating all required credentials. # The first step is to connect to the device. successful_connection = curr_device.connect() if not successful_connection: raise Exception( "Could not connect to device with id {}.".format(id)) # Get the device id. id_data = curr_device.get_data({'device_id': 'none'}) device_internal_id = id_data['device_id'] print 'Device id: ' + device_internal_id # Pair the device, send the credentials, and clear their local files. deployment = Deployment.get_instance() device_keys = deployment.pair_device(device_internal_id, curr_device.get_name(), device_type) deployment.send_paired_credentials(curr_device, device_keys) deployment.clear_device_keys(device_keys) except Exception, e: return ajaxutils.show_and_return_error_dict(e.message)
def GET_list(self): c.devices_active = 'active' page = DevicesPage() # Ensure the device types are initialized. BluetoothSKADevice.initialize(app_globals.cloudlet.data_folder) ADBSKADevice.initialize(app_globals.cloudlet.data_folder) # Get the overall deployment info. page.deployment = Deployment.find_one() if page.deployment is None: page.deployment_auth_start = 'not set' page.deployment_auth_duration = 'not set' page.deployment_auth_end = 'not set' else: page.deployment_auth_start = page.deployment.auth_start.strftime('%Y-%m-%d %X') page.deployment_auth_duration = page.deployment.auth_duration page.deployment_auth_end = (page.deployment.auth_start + datetime.timedelta(minutes=page.deployment.auth_duration)).strftime('%Y-%m-%d %X') # Get the paired devices. page.paired_devices = PairedDevice.find() return page.render()
def migrate_svm(svm_id, remote_host, remote_ip, encrypted): # Find the SVM. svm = ServiceVM.by_id(svm_id) if svm is None: raise MigrationException("SVM with id %s was not found" % str(svm_id)) # remote_host has host and port. print 'VM found: ' + str(svm) print 'Migrating to remote cloudlet: ' + remote_host # Transfer the metadata. print 'Starting metadata file transfer...' payload = {'svm_json_string': svm.to_json_string()} result, response_text = __send_api_command(remote_host, MIGRATE_METADATA_CMD, encrypted, payload) print 'Metadata was transferred: ' + str(result) # We pause the VM before transferring its disk and memory state. print 'Pausing VM...' was_pause_successful = svm.pause() if not was_pause_successful: raise MigrationException("Cannot pause VM: %s" % str(svm_id)) print 'VM paused.' try: # Transfer the disk image file. print 'Starting disk image file transfer...' payload = {'id': svm_id} disk_image_full_path = os.path.abspath(svm.vm_image.disk_image) files = {'disk_image_file': open(disk_image_full_path, 'rb')} result, response_text = __send_api_command(remote_host, MIGRATE_DISK_CMD, encrypted, payload, files=files) print 'Disk image file was transferred: ' + str(result) # Do the memory state migration. remote_host_name = remote_host.split(':')[0] remote_host_port = remote_host.split(':')[1] print 'Migrating through libvirtd to {} ({})'.format(remote_host_name, remote_ip) svm.migrate(remote_host_name) print 'Memory migration through libvirtd completed' # If needed, ask the remote cloudlet for credentials for the devices associated to the SVM. devices = PairedDevice.by_instance(svm_id) for device in devices: # So that the paired device has a connection id on the remote cloudlet, we set it as this cloudlet's id # plus the device id. Connection id is commonly used with USB or Bluetooth pairing as a way to identify # the ID of the physical connection used when pairing. This gives similar auditing possibilities. print 'Starting remote credentials generation for device {}...'.format(device.device_id) deployment = Deployment.get_instance() connection_id = deployment.cloudlet.get_id() + "-" + device.device_id payload = {'device_id': device.device_id, 'connection_id': connection_id, 'svm_id': svm_id} response, serialized_credentials = __send_api_command(remote_host, MIGRATE_CREDENTIALS_CMD, encrypted, payload) # De-serializing generated data. print serialized_credentials paired_device_data_bundle = PairedDeviceDataBundle() paired_device_data_bundle.fill_from_dict(json.loads(serialized_credentials)) paired_device_data_bundle.cloudlet_ip = remote_ip paired_device_data_bundle.cloudlet_port = remote_host_port print 'Remote credentials to be sent: ' + str(paired_device_data_bundle) # Create the appropriate command. data_contains_only_cloudlet_info = paired_device_data_bundle.auth_password is None if data_contains_only_cloudlet_info: device_command = ConnectToNewCloudletMessage(paired_device_data_bundle) else: device_command = AddTrustedCloudletDeviceMessage(paired_device_data_bundle) # Add device and service id data, and store the message to be picked up by the phone. device_command.device_id = device.device_id device_command.service_id = svm.service_id device_command.save() except Exception as e: # If migration fails, ask remote to remove svm. print 'Error migrating: {}'.format(e.message) print 'Requesting migration abort for cleanup...' payload = {'svm_id': svm_id} result, response_text = __send_api_command(remote_host, MIGRATE_ABORT_CMD, encrypted, payload) # Remove pending migration messages. devices = PairedDevice.by_instance(svm_id) for device in devices: AddTrustedCloudletDeviceMessage.clear_messages(device.device_id) print 'Migration aborted: ' + str(result) raise e # Notify remote cloudlet that migration finished. print 'Asking remote cloudlet to resume migrated VM.' payload = {'id': svm_id} result, response_text = __send_api_command(remote_host, MIGRATE_RESUME_CMD, encrypted, payload) print 'Cloudlet notified: ' + str(result) # Remove the local VM. svm = ServiceVM.by_id(svm_id) svm.stop()
def GET_reauthorize(self, id): deployment = Deployment.get_instance() deployment.reauthorize_device(id) # Go to the main page. return h.redirect_to(controller='devices', action='list')
def POST_pair(self): # Generate secret to display device_type = 'cloudlet' secret = request.params.get('secret', None) ssid = request.params.get('ssid', None) psk = request.params.get('psk', None) print ssid + '-' + psk + '-' + secret connection = request.params.get('connection', None) if connection is None: connection = 'wifi' remote_cloudlet = None try: if connection == 'wifi': # Disable any lingering ad-hoc connections. wifi_adhoc.disable_adhoc_mode() # Set up the ad-hoc network. wifi_adhoc.configure_wpa2_params(ssid, psk) wifi_adhoc.enable_adhoc_mode(SKA_CLIENT_IP) # Connect to the server (cloudlet) in the network. remote_cloudlet_name = "WiFiServer" remote_cloudlet = WiFiSKADevice( { 'host': SKA_SERVER_IP, 'port': int(SKA_SERVER_PORT), 'name': remote_cloudlet_name, 'secret': secret }, fqdn=Cloudlet.get_fqdn()) print 'Connecting to cloudlet server' successful_connection = remote_cloudlet.connect() if not successful_connection: raise Exception( "Could not connect to cloudlet with id {}.".format( ssid)) else: print 'Connected to cloudlet server' # TODO: test this. # Get the device id. id_data = remote_cloudlet.get_data({'device_id': 'none'}) device_internal_id = id_data['device_id'] print 'Device id: ' + device_internal_id # Pair the device, send the credentials, and clear their local files. deployment = Deployment.get_instance() device_keys = deployment.pair_device(device_internal_id, remote_cloudlet.get_name(), device_type) deployment.send_paired_credentials(remote_cloudlet, device_keys) deployment.clear_device_keys(device_keys) except Exception, e: error_message = 'Error connecting or pairing: (' + type( e).__name__ + '): ' + str(e) print error_message return ajaxutils.show_and_return_error_dict(error_message)