def update_ldap_users_from_ad(): # Setup the ldap connection dn = "cn=admin,dc=canvas,dc=virtue,dc=com" ldap = LDAP('', '') ldap.get_ldap_connection() # FIXME - Figure out a soluton for the Hardcoded password # TODO - Fix Hardcoded password for ldap and AD connection ldap.conn.simple_bind_s(dn, "Test123!") # Bind the AD connection ad = LDAP('*****@*****.**', 'Test123!') ad.bind_ad() # Query AD for all users ad_users = ad.query_ad('objectClass', 'user') ldap_usernames = get_ldap_usernames(ldap) # Go through all users in AD for user in ad_users: cn = user[1]['cn'][0] ad_username = user[1]['sAMAccountName'][0] # If a username in AD is not found in ldap then add it if ad_username not in ldap_usernames: new_user = { 'username': ad_username, 'authorizedRoleIds': [], 'name': cn } new_ldap_user = ldap_tools.to_ldap(new_user, 'OpenLDAPuser') ldap.add_obj(new_ldap_user, 'users', 'cusername', throw_error=True) # Check to make sure the key directory exists if (not os.path.exists('{0}/user-keys'.format( os.environ['HOME']))): os.mkdir('{0}/user-keys'.format(os.environ['HOME'])) # Create/Add keys for each user subprocess.check_call([ 'ssh-keygen', '-t', 'rsa', '-f', '{}/user-keys/{}.pem'.format(os.environ['HOME'], ad_username), '-C', '"For Virtue user {0}"'.format(ad_username), '-N', '' ]) # Create a dummy kerberos file for the user. # It'll be regenerated as soon as the user logs in. with open('/tmp/krb5cc_{}'.format(ad_username), 'w') as f: f.write("Error 404: Easter Egg text not found") return ldap
class CreateVirtueThread(threading.Thread): def __init__(self, ldap_user, ldap_password, role_id, user, virtue_id, role=None): super(CreateVirtueThread, self).__init__() self.inst = LDAP(ldap_user, ldap_password) self.role_id = role_id self.role = role self.username = user self.virtue_id = virtue_id def run(self): thread_list.append(self) # Going to need to write to LDAP # self.inst.bind_ldap() dn = 'cn=admin,dc=canvas,dc=virtue,dc=com' self.inst.get_ldap_connection() self.inst.conn.simple_bind_s(dn, 'Test123!') if (self.role == None): role = self.inst.get_obj('cid', self.role_id, objectClass='OpenLDAProle') if (role == () or role == None): return ldap_tools.parse_ldap(role) else: role = self.role virtue = { 'id': self.virtue_id, 'username': self.username, 'roleId': self.role_id, 'applicationIds': [], 'resourceIds': role['startingResourceIds'], 'transducerIds': role['startingTransducerIds'], 'networkRules': role['networkRules'], 'state': 'CREATING', 'ipAddress': 'NULL' } ldap_virtue = ldap_tools.to_ldap(virtue, 'OpenLDAPvirtue') assert self.inst.add_obj(ldap_virtue, 'virtues', 'cid') == 0 virtue_path = 'images/provisioned_virtues/' + virtue['id'] + '.img' try: # For now generate keys and store in local dir subprocess.check_output( shlex.split(('ssh-keygen -t rsa -f {0}/{1}.pem -C' ' "Virtue Key for {1}" -N ""').format( USER_KEY_DIR, virtue['id']))) with open(USER_KEY_DIR + '/' + virtue['id'] + '.pem', 'r') as virtue_key_file: virtue_key = virtue_key_file.read().strip() with open(GALAHAD_KEY_DIR + '/excalibur_pub.pem', 'r') as excalibur_key_file: excalibur_key = excalibur_key_file.read().strip() user_key = subprocess.check_output([ 'ssh-keygen', '-y', '-f', '{0}/{1}.pem'.format(USER_KEY_DIR, self.username) ]) with open(GALAHAD_KEY_DIR + '/rethinkdb_cert.pem', 'r') as rdb_cert_file: rdb_cert = rdb_cert_file.read().strip() with open('/tmp/networkRules-' + virtue['id'], 'w+') as iprules_file: for rule in role['networkRules']: iprules_file.write(rule + '\n') # Create the virtue standby image files standby_virtues = StandbyVirtues(self.role_id) standby_virtues.create_virtue_image_file(self.virtue_id) subprocess.check_call(['sudo', 'python', os.environ['HOME'] + '/galahad/excalibur/' + \ 'call_provisioner.py', '-u', self.username, '-i', virtue['id'], '-n', '/tmp/networkRules-' + virtue['id'], '-b', '/mnt/efs/images/non_provisioned_virtues/' + role['id'] + '.img', '-o', '/mnt/efs/' + virtue_path, '-v', virtue_key, '-e', excalibur_key, '--user_key', user_key, '-r', rdb_cert]) # Enable/disable sensors as specified by the role transducers = {} for tid in role['startingTransducerIds']: transducer = self.inst.get_obj('cid', tid, 'OpenLDAPtransducer', True) if (transducer == ()): continue ldap_tools.parse_ldap(transducer) transducers[tid] = transducer eps = EndPoint_Security(self.inst.email, self.inst.password) all_transducers = json.loads(eps.transducer_list()) for transducer in all_transducers: if transducer['id'] in transducers: config = transducer['startingConfiguration'] ret = eps.transducer_enable(transducer['id'], self.virtue_id, config) else: ret = eps.transducer_disable(transducer['id'], self.virtue_id) virtue['state'] = 'STOPPED' ldap_virtue = ldap_tools.to_ldap(virtue, 'OpenLDAPvirtue') assert self.inst.modify_obj('cid', virtue['id'], ldap_virtue) == 0 except: print('Error while creating Virtue for role {0}:\n{1}'.format( role['id'], traceback.format_exc())) assert self.inst.del_obj('cid', virtue['id'], objectClass='OpenLDAPvirtue', throw_error=True) == 0 os.remove('{0}/{1}.pem'.format(USER_KEY_DIR, virtue['id'])) os.remove('{0}/{1}.pem.pub'.format(USER_KEY_DIR, virtue['id'])) os.remove('/mnt/efs/' + virtue_path)
class AssembleRoleThread(threading.Thread): def __init__(self, ldap_user, ldap_password, role, base_img_name, use_ssh=True): super(AssembleRoleThread, self).__init__() self.inst = LDAP(ldap_user, ldap_password) # Going to need to write to LDAP # self.inst.bind_ldap() dn = 'cn=admin,dc=canvas,dc=virtue,dc=com' self.inst.get_ldap_connection() self.inst.conn.simple_bind_s(dn, 'Test123!') self.role = role self.base_img_name = base_img_name self.use_ssh = use_ssh def run(self): self.role['state'] = 'CREATING' ldap_role = ldap_tools.to_ldap(self.role, 'OpenLDAProle') ret = self.inst.add_obj(ldap_role, 'roles', 'cid', throw_error=True) assert ret == 0 virtue_path = 'images/non_provisioned_virtues/' + self.role[ 'id'] + '.img' key_path = USER_KEY_DIR + '/default-virtue-key.pem' valor_manager = ValorManager() try: # Create the role standby image files standby_roles = StandbyRoles(self.base_img_name, self.role) standby_roles.create_role_image_file() if (self.use_ssh): # Launch by adding a 'virtue' to RethinkDB valor = valor_manager.get_empty_valor() virtue_ip = valor_manager.add_virtue( valor['address'], valor['valor_id'], self.role['id'], virtue_path, True) # send role_create=True) time.sleep(5) # Get Docker login command # Use the AWS Account ID of the Account which has the docker registry, # currently this is in the StarLab account. docker_cmd = subprocess.check_output( shlex.split( 'aws ecr get-login --registry-ids {} --no-include-email ' '--region us-east-2'.format(AWS_ECR_ACCOUNT_NUMBER))) print('docker_cmd: ' + docker_cmd) # Run assembler assembler = Assembler(work_dir='{0}/.{1}_assembly'.format( os.environ['HOME'], self.role['id'])) assembler.assemble_running_vm(self.role['applicationIds'], docker_cmd, key_path, virtue_ip) # Create the virtue standby image files standby_virtues = StandbyVirtues(self.role['id']) standby_virtues.create_standby_virtues() self.role['state'] = 'CREATED' ldap_role = ldap_tools.to_ldap(self.role, 'OpenLDAProle') ret = self.inst.modify_obj('cid', self.role['id'], ldap_role, objectClass='OpenLDAProle', throw_error=True) assert ret == 0 except: print('Error while assembling role {0}:\n{1}'.format( self.role['id'], traceback.format_exc())) self.role['state'] = 'FAILED' ldap_role = ldap_tools.to_ldap(self.role, 'OpenLDAProle') ret = self.inst.modify_obj('cid', self.role['id'], ldap_role, objectClass='OpenLDAProle', throw_error=True) finally: if valor_manager.rethinkdb_manager.get_virtue(self.role['id']): valor_manager.rethinkdb_manager.remove_virtue(self.role['id'])
class EndPoint_Admin(): def __init__(self, user, password): self.inst = LDAP(user, password) self.inst.bind_ldap() self.valor_api = ValorAPI() self.rdb_manager = RethinkDbManager() def application_list(self): try: ldap_applications = self.inst.get_objs_of_type( 'OpenLDAPapplication') assert ldap_applications != None applications = ldap_tools.parse_ldap_list(ldap_applications) return json.dumps(applications) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def resource_create(self, resource): try: resource_keys = ['credentials', 'type', 'unc'] if (set(resource.keys()) != set(resource_keys) and set(resource.keys()) != set(resource_keys + ['id'])): return json.dumps(ErrorCodes.admin['invalidFormat']) if (not isinstance(resource['credentials'], basestring) or not isinstance(resource['type'], basestring) or not isinstance(resource['unc'], basestring)): return json.dumps(ErrorCodes.admin['invalidFormat']) resource['id'] = 'Resource_{}_{}'.format(resource['type'], int(time.time())) ldap_resource = ldap_tools.to_ldap(resource, 'OpenLDAPresource') self.inst.add_obj(ldap_resource, 'resources', 'cid', throw_error=True) return json.dumps(resource) except Exception as e: return json.dumps(ErrorCodes.admin['unspecifiedError']) def resource_destroy(self, resourceId): try: resource = self.inst.get_obj('cid', resourceId, 'OpenLDAPresource', True) if (resource == ()): return json.dumps(ErrorCodes.admin['invalidId']) ldap_tools.parse_ldap(resource) # KL --- add check if in use ldap_virtues = self.inst.get_objs_of_type('OpenLDAPvirtue') virtues = ldap_tools.parse_ldap_list(ldap_virtues) if any(resourceId in virtue['resourceIds'] for virtue in virtues): return json.dumps(ErrorCodes.admin['virtueUsingResource']) self.inst.del_obj('cid', resource['id'], throw_error=True) except: print('Error while deleting {}:\n{}'.format( resource['id'], traceback.format_exc())) return json.dumps(ErrorCodes.user['serverDestroyError']) return json.dumps(ErrorCodes.admin['success']) def resource_get(self, resourceId): try: resource = self.inst.get_obj('cid', resourceId, objectClass='OpenLDAPresource', throw_error=True) if (resource == ()): return json.dumps(ErrorCodes.admin['invalidId']) ldap_tools.parse_ldap(resource) return json.dumps(resource) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def resource_list(self): try: ldap_resources = self.inst.get_objs_of_type('OpenLDAPresource') assert ldap_resources != None resources = ldap_tools.parse_ldap_list(ldap_resources) return json.dumps(resources) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def resource_attach(self, resourceId, virtueId): try: resource = self.inst.get_obj('cid', resourceId, objectClass='OpenLDAPresource', throw_error=True) if (resource == ()): return json.dumps(ErrorCodes.admin['invalidResourceId']) ldap_tools.parse_ldap(resource) virtue = self.inst.get_obj('cid', virtueId, objectClass='OpenLDAPvirtue', throw_error=True) if (virtue == ()): return json.dumps(ErrorCodes.admin['invalidVirtueId']) ldap_tools.parse_ldap(virtue) #if (virtue['state'] == 'DELETING'): # return json.dumps(ErrorCodes.admin['invalidVirtueState']) if (virtue['state'] != 'STOPPED'): return json.dumps(ErrorCodes.admin['invalidVirtueState']) if (resourceId in virtue['resourceIds']): return json.dumps(ErrorCodes.admin['cantAttach']) virtue['resourceIds'].append(resourceId) self.inst.modify_obj('cid', virtue['id'], ldap_tools.to_ldap(virtue, 'OpenLDAPvirtue'), objectClass='OpenLDAPvirtue', throw_error=True) #return json.dumps(ErrorCodes.admin['notImplemented']) return json.dumps(ErrorCodes.admin['success']) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def resource_detach(self, resourceId, virtueId): try: resource = self.inst.get_obj('cid', resourceId, objectClass='OpenLDAPresource', throw_error=True) if (resource == ()): return json.dumps(ErrorCodes.admin['invalidResourceId']) ldap_tools.parse_ldap(resource) virtue = self.inst.get_obj('cid', virtueId, objectClass='OpenLDAPvirtue', throw_error=True) if (virtue == ()): return json.dumps(ErrorCodes.admin['invalidVirtueId']) ldap_tools.parse_ldap(virtue) if (resourceId not in virtue['resourceIds']): return json.dumps(ErrorCodes.admin['cantDetach']) if (virtue['state'] != 'STOPPED'): return json.dumps(ErrorCodes.admin['invalidVirtueState']) virtue['resourceIds'].remove(resourceId) self.inst.modify_obj('cid', virtue['id'], ldap_tools.to_ldap(virtue, 'OpenLDAPvirtue'), objectClass='OpenLDAPvirtue', throw_error=True) #return json.dumps(ErrorCodes.admin['notImplemented']) return json.dumps(ErrorCodes.admin['success']) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def role_create(self, role, use_ssh=True, unity_img_name=None): try: role_keys = [ 'name', 'version', 'applicationIds', 'startingResourceIds', 'startingTransducerIds', 'networkRules' ] if (set(role.keys()) != set(role_keys) and set(role.keys()) != set(role_keys + ['id'])): return json.dumps(ErrorCodes.admin['invalidFormat']) if (not isinstance(role['name'], basestring) or not isinstance(role['version'], basestring) or type(role['applicationIds']) != list or type(role['startingResourceIds']) != list or type(role['networkRules']) != list or type(role['startingTransducerIds']) != list): return json.dumps(ErrorCodes.admin['invalidFormat']) if not role['applicationIds']: return json.dumps(ErrorCodes.admin['NoApplicationId']) default_unity_size = 3 # Measured in GB. for a in role['applicationIds']: app_test = self.inst.get_obj('cid', a, objectClass='OpenLDAPapplication', throw_error=True) if (app_test == ()): return json.dumps(ErrorCodes.admin['invalidApplicationId']) ldap_tools.parse_ldap(app_test) if (app_test['os'] == 'WINDOWS'): if (app_test['name'].startswith('Microsoft Office')): default_unity_size = default_unity_size + 7 else: default_unity_size = default_unity_size + 3 else: default_unity_size = default_unity_size + 2 for r in role['startingResourceIds']: res_test = self.inst.get_obj('cid', r, objectClass='OpenLDAPresource', throw_error=True) if (res_test == ()): return json.dumps(ErrorCodes.admin['invalidResourceId']) ldap_transducers = self.inst.get_objs_of_type('OpenLDAPtransducer') assert ldap_transducers != None all_transducers = ldap_tools.parse_ldap_list(ldap_transducers) for t in role['startingTransducerIds']: if (t not in [tr['id'] for tr in all_transducers]): return json.dumps(ErrorCodes.admin['invalidTransducerId']) new_role = copy.deepcopy(role) for t in all_transducers: if (t['startEnabled'] and t['id'] not in role['startingTransducerIds']): new_role['startingTransducerIds'].append(t['id']) new_role['id'] = '{0}{1}'.format( new_role['name'].lower().replace(' ', '_'), int(time.time())) if (unity_img_name == None): closest_fit = 0 for img in os.listdir('/mnt/efs/images/unities'): img_size = int(img.replace('GB.img', '')) if (img_size >= default_unity_size and (closest_fit == 0 or closest_fit > img_size)): closest_fit = img_size if (closest_fit != 0): unity_img_name = '{}GB'.format(closest_fit) else: return json.dumps({ 'status': 'failed', 'result': [ 17, ('Could not automatically find a usable unity' ' for this role. Please specify a unity' ' image.') ] }) if ((unity_img_name + '.img') not in os.listdir('/mnt/efs/images/unities')): return json.dumps({ 'status': 'failed', 'result': [ 17, ('Could not find a unity with the name' ' ({})').format(unity_img_name) ] }) try: # Call a controller thread to create and assemble the new image thr = AssembleRoleThread(self.inst.email, self.inst.password, new_role, unity_img_name, use_ssh=use_ssh) except AssertionError: return json.dumps(ErrorCodes.admin['storageError']) thr.start() return json.dumps({'id': new_role['id'], 'name': new_role['name']}) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) # Destroy the specified role def role_destroy(self, roleId, use_nfs=True): try: role = self.inst.get_obj('cid', roleId, 'OpenLDAProle', True) if (role == ()): return json.dumps(ErrorCodes.admin['invalidId']) ldap_tools.parse_ldap(role) # Check if any virtues exist with given role virtues = self.inst.get_objs_of_type('OpenLDAPvirtue') for virtue in virtues: ldap_tools.parse_ldap(virtue[1]) if (virtue[1]['roleId'] == roleId): # A Virtue exists for this role - Unable to destroy role virtueUsingRoleError = [] virtueUsingRoleError.append({ 'Virtue using the ' 'specified role exists': virtue[1]['id'] }) virtueUsingRoleError.append( ErrorCodes.admin['virtueUsingRole']) return json.dumps(virtueUsingRoleError) # Check if any user is authorized for the given role users = self.inst.get_objs_of_type('OpenLDAPuser') for user in users: ldap_tools.parse_ldap(user[1]) if (roleId in user[1]['authorizedRoleIds']): # A User exists with this role authorized - Unable to # destroy role userUsingRoleError = [] userUsingRoleError.append({ 'User authorized for the ' 'specified role exists': user[1]['username'] }) userUsingRoleError.append( ErrorCodes.admin['userUsingRole']) return json.dumps(userUsingRoleError) try: self.inst.del_obj('cid', roleId, throw_error=True) if (use_nfs): subprocess.check_call([ 'sudo', 'rm', '/mnt/efs/images/non_provisioned_virtues/' + role['id'] + '.img' ]) # Delete the Standby virtue role image files files = os.listdir('/mnt/efs/images/provisioned_virtues/') standby_files = (file for file in files if role['id'] + '_STANDBY_VIRTUE_' in file) for standby_file in standby_files: subprocess.check_call([ 'sudo', 'rm', '/mnt/efs/images/provisioned_virtues/' + standby_file ]) except: print('Error while deleting {0}:\n{1}'.format( role['id'], traceback.format_exc())) return json.dumps(ErrorCodes.admin['roleDestroyError']) return json.dumps(ErrorCodes.admin['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def role_list(self): try: ldap_roles = self.inst.get_objs_of_type('OpenLDAProle') assert ldap_roles != None roles = ldap_tools.parse_ldap_list(ldap_roles) return json.dumps(roles) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def system_export(self): return json.dumps(ErrorCodes.admin['notImplemented']) def system_import(self, data): return json.dumps(ErrorCodes.admin['notImplemented']) def test_import_user(self, which): return json.dumps(ErrorCodes.admin['notImplemented']) def test_import_application(self, which): return json.dumps(ErrorCodes.admin['notImplemented']) def test_import_role(self, which): return json.dumps(ErrorCodes.admin['notImplemented']) def user_list(self): try: # Check AD and update user list in ldap if required update_ldap_users_from_ad() ldap_users = self.inst.get_objs_of_type('OpenLDAPuser') assert ldap_users != None users = ldap_tools.parse_ldap_list(ldap_users) return json.dumps(users) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def user_get(self, username): try: # Check AD and update user list in ldap if required update_ldap_users_from_ad() user = self.inst.get_obj('cusername', username, objectClass='OpenLDAPuser', throw_error=True) if (user == ()): return json.dumps(ErrorCodes.admin['invalidUsername']) ldap_tools.parse_ldap(user) return json.dumps(user) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def user_virtue_list(self, username): try: # Check AD and update user list in ldap if required update_ldap_users_from_ad() user = self.inst.get_obj('cusername', username, objectClass='OpenLDAPuser') if (user == ()): return json.dumps(ErrorCodes.admin['invalidUsername']) elif (user == None): return json.dumps(ErrorCodes.admin['unspecifiedError']) ep = EndPoint(self.inst.email, self.inst.password) return ep.user_virtue_list(username) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def user_role_authorize(self, username, roleId): try: # Check AD and update user list in ldap if required update_ldap_users_from_ad() user = self.inst.get_obj('cusername', username, objectClass='OpenLDAPuser', throw_error=True) if (user == ()): return json.dumps(ErrorCodes.admin['invalidUsername']) ldap_tools.parse_ldap(user) role = self.inst.get_obj('cid', roleId, objectClass='OpenLDAProle', throw_error=True) if (role == ()): if (roleId in user['authorizedRoleIds']): # The user is authorized for a nonexistent role... # Remove it from their list? pass return json.dumps(ErrorCodes.admin['invalidRoleId']) ldap_tools.parse_ldap(role) if (roleId in user['authorizedRoleIds']): return json.dumps(ErrorCodes.admin['userAlreadyAuthorized']) user['authorizedRoleIds'].append(roleId) ldap_user = ldap_tools.to_ldap(user, 'OpenLDAPuser') self.inst.modify_obj('cusername', username, ldap_user, objectClass='OpenLDAPuser', throw_error=True) return json.dumps(ErrorCodes.admin['success']) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def user_role_unauthorize(self, username, roleId): try: user = self.inst.get_obj('cusername', username, objectClass='OpenLDAPuser', throw_error=True) if (user == ()): return json.dumps(ErrorCodes.admin['invalidUsername']) ldap_tools.parse_ldap(user) role = self.inst.get_obj('cid', roleId, objectClass='OpenLDAProle', throw_error=True) if (roleId not in user['authorizedRoleIds'] and role == ()): # If the role does not exist AND the user isn't 'authorized' # for it, return error. If the user is not authorized for a # real role, return error. If the user is authorized for a # nonexistent role, the admin may be trying to clean up an error return json.dumps(ErrorCodes.admin['invalidRoleId']) elif (roleId not in user['authorizedRoleIds']): return json.dumps(ErrorCodes.admin['userNotAlreadyAuthorized']) ldap_tools.parse_ldap(role) virtues = self.inst.get_objs_of_type('OpenLDAPvirtue') for v in virtues: ldap_tools.parse_ldap(v[1]) if (v[1]['username'] == username and v[1]['roleId'] == roleId): # Todo: Check if the user is logged on return json.dumps(ErrorCodes.admin['userUsingVirtue']) for r in user['authorizedRoleIds']: if (r == roleId): user['authorizedRoleIds'].remove(r) del r ldap_user = ldap_tools.to_ldap(user, 'OpenLDAPuser') self.inst.modify_obj('cusername', username, ldap_user, objectClass='OpenLDAPuser', throw_error=True) return json.dumps(ErrorCodes.admin['success']) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) # Create a virtue for the specified role, but do not launch it yet def virtue_create(self, username, roleId, use_nfs=True): try: user = None role = None resources = [] virtue_dict = {} user = self.inst.get_obj('cusername', username, 'OpenLDAPuser') if (user == None or user == ()): return json.dumps(ErrorCodes.admin['invalidUsername']) ldap_tools.parse_ldap(user) role = self.inst.get_obj('cid', roleId, 'OpenLDAProle', True) if (role == ()): return json.dumps(ErrorCodes.admin['invalidRoleId']) ldap_tools.parse_ldap(role) if (roleId not in user['authorizedRoleIds']): return json.dumps(ErrorCodes.admin['userNotAlreadyAuthorized']) if (role.get('state', 'CREATED') != 'CREATED'): return json.dumps(ErrorCodes.admin['invalidRoleState']) virtue = None curr_virtues = self.inst.get_objs_of_type('OpenLDAPvirtue') for v in curr_virtues: ldap_tools.parse_ldap(v[1]) if (v[1]['username'] == username and v[1]['roleId'] == roleId): return json.dumps( ErrorCodes.user['virtueAlreadyExistsForRole']) for rid in role['startingResourceIds']: resource = self.inst.get_obj('cid', rid, 'OpenLDAPresource', True) if (resource == ()): continue ldap_tools.parse_ldap(resource) resources.append(resource) virtue_id = 'Virtue_{0}_{1}'.format( role['name'].lower().replace(' ', '_'), int(time.time())) thr = CreateVirtueThread(self.inst.email, self.inst.password, role['id'], username, virtue_id, role=role) if (use_nfs): thr.start() else: virtue = { 'id': virtue_id, 'username': username, 'roleId': roleId, 'applicationIds': [], 'resourceIds': role['startingResourceIds'], 'transducerIds': role['startingTransducerIds'], 'networkRules': role['networkRules'], 'state': 'STOPPED', 'ipAddress': 'NULL' } ldap_virtue = ldap_tools.to_ldap(virtue, 'OpenLDAPvirtue') self.inst.add_obj(ldap_virtue, 'virtues', 'cid') # Return the whole thing # return json.dumps( virtue ) # Return a json of the id and ip address return json.dumps({'ipAddress': 'NULL', 'id': virtue_id}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) # Destroy the specified stopped virtue def virtue_destroy(self, virtueId, use_nfs=True): try: virtue = self.inst.get_obj('cid', virtueId, 'OpenLDAPvirtue', True) if (virtue == ()): return json.dumps(ErrorCodes.admin['invalidId']) ldap_tools.parse_ldap(virtue) if (virtue['state'] != 'STOPPED'): return json.dumps(ErrorCodes.user['virtueNotStopped']) try: if (use_nfs): subprocess.check_call([ 'sudo', 'rm', '/mnt/efs/images/provisioned_virtues/' + virtue['id'] + '.img' ]) self.inst.del_obj('cid', virtue['id'], throw_error=True) except: print('Error while deleting {0}:\n{1}'.format( virtue['id'], traceback.format_exc())) return json.dumps(ErrorCodes.user['serverDestroyError']) self.rdb_manager.destroy_virtue(virtue['id']) return json.dumps(ErrorCodes.admin['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def virtue_reload_state(self, virtueId): try: virtue = self.inst.get_obj('cid', virtueId, 'OpenLDAPvirtue', True) if (virtue == ()): return json.dumps(ErrorCodes.user['invalidId']) ldap_tools.parse_ldap(virtue) updated_virtue = copy.deepcopy(virtue) rdb_manager = RethinkDbManager() rdb_virtue = rdb_manager.get_virtue(virtueId) if (rdb_virtue == None): updated_virtue['state'] = 'STOPPED' updated_virtue['ipAddress'] = 'NULL' else: updated_virtue['state'] = 'RUNNING' updated_virtue['ipAddress'] = rdb_virtue['guestnet'] if (updated_virtue != virtue): ldap_virtue = ldap_tools.to_ldap(updated_virtue, 'OpenLDAPvirtue') self.inst.modify_obj('cid', virtueId, ldap_virtue, 'OpenLDAPvirtue', True) return json.dumps(ErrorCodes.user['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def valor_create(self): try: valor_id = self.valor_api.valor_create() return json.dumps({'valor_id': valor_id}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def valor_launch(self, valor_id): try: valor_id = self.valor_api.valor_launch(valor_id) return json.dumps({'valor_id': valor_id}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def valor_stop(self, valor_id): try: valor_id = self.valor_api.valor_stop(valor_id) return json.dumps({'valor_id': valor_id}) except Exception as exception: print('Error:\n{0}'.format(traceback.format_exc())) # Virtue/s exists on this valor - Unable to stop valor return json.dumps({ 'status': 'failed', 'result': [11, exception.message] }) def valor_destroy(self, valor_id): try: valor_id = self.valor_api.valor_destroy(valor_id) return json.dumps({'valor_id': valor_id}) except Exception as exception: print('Error:\n{0}'.format(traceback.format_exc())) # Virtue/s exists on this valor - Unable to destroy valor return json.dumps({ 'status': 'failed', 'result': [11, exception.message] }) def valor_list(self): try: valors = self.valor_api.valor_list() return json.dumps(valors) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def valor_create_pool(self, number_of_valors): try: valor_ids = self.valor_api.valor_create_pool(number_of_valors) return json.dumps({'valor_ids': valor_ids}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def valor_migrate_virtue(self, virtue_id, destination_valor_id): try: valor_id = self.valor_api.valor_migrate_virtue( virtue_id, destination_valor_id) return json.dumps({'valor_id': valor_id}) except Exception as exception: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps({ 'status': 'failed', 'result': [11, exception.message] }) def galahad_get_id(self): try: instance_data = AWS.get_instance_info() return json.dumps(instance_data['instance-id']) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def application_add(self, application): try: app = copy.copy(application) if (set(app.keys()) != set(['id', 'name', 'version', 'os']) and set(app.keys()) != set( ['id', 'name', 'version', 'os', 'port'])): return json.dumps(ErrorCodes.admin['invalidFormat']) if (isinstance(app.get('port'), basestring)): app['port'] = int(app['port']) if (not isinstance(app['id'], basestring) or not isinstance(app['name'], basestring) or not isinstance(app['version'], basestring) or type(app.get('port', 0)) != int): return json.dumps(ErrorCodes.admin['invalidFormat']) if (app['os'] != 'LINUX' and app['os'] != 'WINDOWS'): return json.dumps(ErrorCodes.admin['invalidFormat']) if (self.inst.get_obj('cid', app['id'], throw_error=True) != ()): return json.dumps(ErrorCodes.admin['invalidId']) ecr_auth_json = subprocess.check_output([ 'aws', 'ecr', 'get-authorization-token', '--registry-ids', '703915126451', '--output', 'json', '--region', 'us-east-2' ]) ecr_auth = json.loads(ecr_auth_json.decode()) docker_registry = ecr_auth['authorizationData'][0]['proxyEndpoint'] docker_token = ecr_auth['authorizationData'][0][ 'authorizationToken'] # Since the user is only adding the app, not creating it, make sure # the image is already in the docker repo. response = requests.get( '{0}/v2/starlab-virtue/tags/list'.format(docker_registry), headers={'Authorization': 'Basic ' + docker_token}) if ('virtue-' + app['id'] not in response.json()['tags']): return json.dumps(ErrorCodes.admin['imageNotFound']) ldap_app = ldap_tools.to_ldap(app, 'OpenLDAPapplication') ret = self.inst.add_obj(ldap_app, 'virtues', 'cid') assert ret == 0 return json.dumps(ErrorCodes.admin['success']) except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError']) def auto_migration_start(self, migration_interval=None): try: self.valor_api.auto_migration_start(migration_interval) return json.dumps(ErrorCodes.admin['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def auto_migration_stop(self): try: self.valor_api.auto_migration_stop() return json.dumps(ErrorCodes.admin['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def auto_migration_status(self): try: status, interval = self.valor_api.auto_migration_status() if status: migration_status = 'ON' return json.dumps({ 'auto_migration_status': migration_status, 'auto_migration_interval': interval }) else: migration_status = 'OFF' return json.dumps({'auto_migration_status': migration_status}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def virtue_introspect_start(self, virtue_id, interval=None, modules=None): try: self.rdb_manager.introspect_virtue_start(virtue_id, interval, modules) return json.dumps({'virtue_id': virtue_id}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def virtue_introspect_stop(self, virtue_id): try: self.rdb_manager.introspect_virtue_stop(virtue_id) return json.dumps({'virtue_id': virtue_id}) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def virtue_introspect_start_all(self, interval=None, modules=None): try: virtues_raw = self.inst.get_objs_of_type('OpenLDAPvirtue') if (virtues_raw == None): return json.dumps(ErrorCodes.user['unspecifiedError']) for virtue in virtues_raw: ldap_tools.parse_ldap(virtue[1]) virtue_running = (virtue[1]['state'] == 'RUNNING') if virtue_running: self.rdb_manager.introspect_virtue_start( virtue[1]['id'], interval, modules) return json.dumps(ErrorCodes.admin['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def virtue_introspect_stop_all(self): try: virtues_raw = self.inst.get_objs_of_type('OpenLDAPvirtue') if (virtues_raw == None): return json.dumps(ErrorCodes.user['unspecifiedError']) for virtue in virtues_raw: ldap_tools.parse_ldap(virtue[1]) virtue_running = (virtue[1]['state'] == 'RUNNING') if virtue_running: self.rdb_manager.introspect_virtue_stop(virtue[1]['id']) return json.dumps(ErrorCodes.admin['success']) except: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.user['unspecifiedError']) def _set_introspection_ldap(self, virtueId, isEnabled): introsection_id = 'introspection' virtue = self.inst.get_obj('cid', virtueId, 'OpenLDAPvirtue', True) if virtue is None or virtue == (): return json.dumps(ErrorCodes.admin['invalidVirtueId']) ldap_tools.parse_ldap(virtue) new_t_list = json.loads(virtue['transducerIds']) if isEnabled: if introsection_id not in new_t_list: new_t_list.append(introsection_id) else: if introsection_id in new_t_list: new_t_list.remove(introsection_id) virtue['transducerIds'] = json.dumps(new_t_list) ret = self.inst.modify_obj( 'cid', virtueId, ldap_tools.to_ldap(virtue, 'OpenLDAPvirtue'), 'OpenLDAPvirtue', True) if ret != 0: return json.dumps(ErrorCodes.user['unspecifiedError']) return json.dumps(ErrorCodes.admin['success']) def _set_introspection_role(self, isEnabled): introspection_id = 'introspection' try: ldap_roles = self.inst.get_objs_of_type('OpenLDAProle') assert ldap_roles != None roles = ldap_tools.parse_ldap_list(ldap_roles) for role in roles: print(role) print(role['startingTransducerIds']) new_t_list = role['startingTransducerIds'] if isEnabled: if introspection_id not in new_t_list: new_t_list.append(introspection_id) else: if introspection_id in new_t_list: new_t_list.remove(introspection_id) role['startingTransducerIds'] = new_t_list ret = self.inst.modify_obj( 'cid', role['id'], ldap_tools.to_ldap(role, 'OpenLDAProle'), 'OpenLDAProle', True) if ret != 0: return json.dumps(ErrorCodes.user['unspecifiedError']) return True except Exception as e: print('Error:\n{0}'.format(traceback.format_exc())) return json.dumps(ErrorCodes.admin['unspecifiedError'])