def do_version_update(db_versions, code_versions): from anchore_engine.db import db_anchore, session_scope with session_scope() as dbsession: db_anchore.add(code_versions['service_version'], code_versions['db_version'], code_versions, session=dbsession) return(True)
def initialize(localconfig=None, versions=None, bootstrap_db=False, specific_tables=None, bootstrap_users=False): """ Initialize the db for use. Optionally bootstrap it and optionally only for specific entities. :param versions: :param bootstrap_db: :param specific_entities: a list of entity classes to initialize if a subset is desired. Expects a list of classes. :return: """ global engine, Session if versions is None: versions = {} #localconfig = anchore_engine.configuration.localconfig.get_config() ret = True try: db_auth = localconfig['credentials']['database'] # connect to DB using db_connect from configuration db_connect = None db_connect_args = {} db_pool_size = 10 db_pool_max_overflow = 20 if 'db_connect' in db_auth and db_auth['db_connect']: db_connect = db_auth['db_connect'] if 'db_connect_args' in db_auth and db_auth['db_connect_args']: db_connect_args = db_auth['db_connect_args'] if 'db_pool_size' in db_auth: db_pool_size = int(db_auth['db_pool_size']) if 'db_pool_max_overflow' in db_auth: db_pool_max_overflow = int(db_auth['db_pool_max_overflow']) except: raise Exception( "could not locate credentials->database entry from configuration: add 'database' section to 'credentials' section in configuration file" ) db_connect_retry_max = 3 for count in range(0, db_connect_retry_max): try: if db_connect: try: if db_connect.startswith('sqlite://'): # Special case for testing with sqlite. Not for production use, unit tests only engine = sqlalchemy.create_engine(db_connect, echo=False) else: engine = sqlalchemy.create_engine( db_connect, connect_args=db_connect_args, echo=False, pool_size=db_pool_size, max_overflow=db_pool_max_overflow) except Exception as err: raise Exception("could not connect to DB - exception: " + str(err)) else: raise Exception( "could not locate db_connect string from configuration: add db_connect parameter to configuration file" ) # set up the global session try: Session = sessionmaker(bind=engine) except Exception as err: raise Exception("could not create DB session - exception: " + str(err)) # set up thread-local session factory init_thread_session() # create try: if specific_tables: logger.info( 'Initializing only a subset of tables as requested: {}' .format(specific_tables)) Base.metadata.create_all(engine, tables=specific_tables) else: Base.metadata.create_all(engine) except Exception as err: raise Exception( "could not create/re-create DB tables - exception: " + str(err)) break except Exception as err: if count > db_connect_retry_max: raise Exception( "could not establish connection to DB after retry - last exception: " + str(err)) else: log.err( "could not connect to db, retrying in 10 seconds - exception: " + str(err)) time.sleep(10) if bootstrap_db: from anchore_engine.db import db_anchore, db_users with session_scope() as dbsession: # version check version_record = db_anchore.get(session=dbsession) if not version_record: db_anchore.add(versions['service_version'], versions['db_version'], versions, session=dbsession) version_record = db_anchore.get(session=dbsession) if bootstrap_users: # system user try: system_user_record = db_users.get('anchore-system', session=dbsession) if not system_user_record: rc = db_users.add('anchore-system', str(uuid.uuid4()), {'active': True}, session=dbsession) else: db_users.update(system_user_record['userId'], system_user_record['password'], {'active': True}, session=dbsession) except Exception as err: raise Exception( "Initialization failed: could not fetch/add anchore-system user from/to DB - exception: " + str(err)) try: for userId in localconfig['credentials']['users']: if not localconfig['credentials']['users'][userId]: localconfig['credentials']['users'][userId] = {} cuser = localconfig['credentials']['users'][userId] password = cuser.pop('password', None) email = cuser.pop('email', None) if password and email: # try: # from passlib.hash import pbkdf2_sha256 # hashpw = pbkdf2_sha256.encrypt(password, rounds=200000, salt_size=16) # password = hashpw # except: # pass db_users.add(userId, password, { 'email': email, 'active': True }, session=dbsession) else: raise Exception( "user defined but has empty password/email: " + str(userId)) user_records = db_users.get_all(session=dbsession) for user_record in user_records: if user_record['userId'] == 'anchore-system': continue if user_record['userId'] not in localconfig[ 'credentials']['users']: logger.info( "flagging user '" + str(user_record['userId']) + "' as inactive (in DB, not in configuration)") db_users.update(user_record['userId'], user_record['password'], {'active': False}, session=dbsession) except Exception as err: raise Exception( "Initialization failed: could not add users from config into DB - exception: " + str(err)) print("Starting up version: " + json.dumps(versions)) print("\tDB version: " + json.dumps(version_record)) try: rc = do_upgrade(version_record, versions) if rc: # if successful upgrade, set the DB values to the incode values with session_scope() as dbsession: db_anchore.add(versions['service_version'], versions['db_version'], versions, session=dbsession) except Exception as err: raise Exception( "Initialization failed: upgrade failed - exception: " + str(err)) return (ret)