Exemplo n.º 1
0
def register_nest_endpoints(flask_app, project_env, authenticator):
    db_engine = nest_db.get_global_sqlalchemy_engine()
    sqla_md = nest_db.get_global_sqlalchemy_metadata()
    if ProjectEnv.hello_world_instance() == project_env:
        import nest_py.hello_world.flask.hw_flask as hw_flask
        nest_endpoints = hw_flask.get_nest_endpoints(db_engine, sqla_md,
                                                     authenticator)
    elif ProjectEnv.mmbdb_instance() == project_env:
        import nest_py.omix.flask.omix_flask as omix_flask
        nest_endpoints = omix_flask.get_nest_endpoints(db_engine, sqla_md,
                                                       authenticator)
    elif ProjectEnv.knoweng_instance() == project_env:
        import nest_py.knoweng.flask.knoweng_flask as knoweng_flask
        nest_endpoints = knoweng_flask.get_nest_endpoints(
            db_engine, sqla_md, authenticator)
    else:
        raise Exception("Unknown project when registering endpoints")

    for flask_ep in nest_endpoints.get_flask_endpoints():
        nest_ep = nest_endpoints.get_endpoint(flask_ep)
        relative_flask_rule = nest_ep.get_flask_rule()
        rule = API_PREFIX + relative_flask_rule
        print('registering flask rule: ' + str(rule))
        flask_ep = nest_ep.get_flask_endpoint()
        renderer = nest_ep.handle_request
        flask_app.add_url_rule(rule,
                               flask_ep,
                               view_func=renderer,
                               methods=['GET', 'POST', 'PATCH', 'DELETE'])
    return
Exemplo n.º 2
0
def setup_db():
    #these tests are detructive of the nest_users table in
    #the database, so point nest_users at a different table
    #for the duration of these tests
    nest_users.COLLECTION_NAME = 'test_users'
    md = nest_db.get_global_sqlalchemy_metadata()
    sqla_maker = core_db.get_nest_users_sqla_maker()
    users_tbl = sqla_maker.get_sqla_table(md)
    
    # initialize the test_projects db table
    projects.COLLECTION_NAME = 'test_projects'
    sp = SecurityPolicy(anyone_can_write=True, anyone_can_read_all=False)
    proj_sqla_maker = TablelikeSqlaMaker(projects.generate_schema(), security_policy=sp)
    proj_tbl = proj_sqla_maker.get_sqla_table(md)
    
    engine = nest_db.get_global_sqlalchemy_engine()
    if users_tbl.exists(engine):
        print('dropping existing table test_users')
        users_tbl.drop(engine)
    users_tbl.create(engine)
    print('created table test_users')
    
    # This is a side-effect of KNOW-516
    # TODO: Update this when fixing/moving db_ops_utils.ensure_default_project()
    if proj_tbl.exists(engine):
        print('dropping existing table test_projects')
        proj_tbl.drop(engine)
    proj_tbl.create(engine)
    print('created table test_projects')
    return
Exemplo n.º 3
0
def init_crud_clients():
    config = nest_config.generate_config(ProjectEnv.knoweng_instance(),
                                         RunLevel.development_instance())
    init_token_maker(config['JWT_SECRET'], config['JWT_ISSUER'],
                     config['JWT_AUDIENCES'])

    global SCHEMA_REGISTRY
    SCHEMA_REGISTRY = knoweng_schemas.get_schemas()
    global CLIENT_REGISTRY
    CLIENT_REGISTRY = dict()

    #make db clients

    #TODO: knoweng should declare the db it's using, but for now
    #the default postgres container on localhost is all there is,
    #which is what the global db engine defaults to.
    engine = nest_db.get_global_sqlalchemy_engine()
    sqla_md = nest_db.get_global_sqlalchemy_metadata()
    db_client_makers = knoweng_db.get_sqla_makers()
    for name in DB_COLLECTIONS:
        cm = db_client_makers[name]
        client = cm.get_db_client(engine, sqla_md)
        CLIENT_REGISTRY[name] = client

    #make api clients

    http_client = get_http_client()
    api_client_makers = knoweng_api_clients.get_api_client_makers()
    for name in API_COLLECTIONS:
        cm = api_client_makers[name]
        crud_client = cm.get_crud_client(http_client)
        CLIENT_REGISTRY[name] = crud_client
    return
Exemplo n.º 4
0
def _make_db_engine(project_env):
    db_config = nest_db.generate_db_config(project_env=project_env)
    db_config['verbose_logging'] = False
    sqla_res = nest_db.GLOBAL_SQLA_RESOURCES
    sqla_res.set_config(db_config)
    nest_db.set_global_sqla_resources(sqla_res)
    db_engine = nest_db.get_global_sqlalchemy_engine().connect()
    return db_engine 
Exemplo n.º 5
0
def make_users_db_client():
    md = nest_db.get_global_sqlalchemy_metadata()
    sqla_maker = core_db.get_nest_users_sqla_maker()
    engine = nest_db.get_global_sqlalchemy_engine()

    sys_user = core_db.get_system_user()
    db_client = sqla_maker.get_db_client(engine, md)
    db_client.set_requesting_user(sys_user)
    return db_client
Exemplo n.º 6
0
def ensure_tables_in_db():
    engine = nest_db.get_global_sqlalchemy_engine()
    md = nest_db.get_global_sqlalchemy_metadata()
    for tbl in md.sorted_tables:
        if tbl.exists(engine):
            print(' exists : ' + str(tbl.name))
        else:
            tbl.create(engine)
            print(' CREATED: ' + str(tbl.name))
    return True
Exemplo n.º 7
0
def ensure_default_project(nest_user):
    # initialize the projects db client
    schema = projects.generate_schema()
    sp = SecurityPolicy(anyone_can_write=True, anyone_can_read_all=False)
    sqla_maker = TablelikeSqlaMaker(schema, security_policy=sp)

    db_engine = nest_db.get_global_sqlalchemy_engine()
    md = nest_db.get_global_sqlalchemy_metadata()

    inspector = Inspector.from_engine(db_engine)

    # Noop for non-knoweng projects
    if not 'projects' in inspector.get_table_names():
        print 'No projects table defined... skipping'
        return None

    projects_client = sqla_maker.get_db_client(db_engine, md)
    projects_client.set_requesting_user(nest_user)

    uname = nest_user.get_username()
    owner_id = nest_user.get_nest_id().get_value()
    default_project_name = "Default Project"
    fltr = {'name': default_project_name, 'owner_id': owner_id}
    existings = projects_client.simple_filter_query(fltr)
    if len(existings) == 0:
        #user hasn't accessed Nest before, create new default project
        new_default_project = ProjectDTO(default_project_name)
        raw_tle = new_default_project.to_tablelike_entry()
        default_project_tle = projects_client.create_entry(raw_tle)
        print(" Created: Default Project for user '" + uname + "'")
    elif len(existings) == 1:
        #found a valid record for this project in the DB
        default_project_tle = existings[0]
        print(" Exists: Default Project for user '" + uname + "'")
    else:
        print(" WARNING: Multiple Default Projects detected for username '" +
              uname + "'")
        default_project_tle = existings[0]

    if default_project_tle is None:
        default_project = None
        print('FAILURE ensuring default project: ' + uname)
    else:
        default_project = ProjectDTO.from_tablelike_entry(default_project_tle)
        print('ensured default project: ' + uname)

    return default_project
Exemplo n.º 8
0
def seed_users(project_env, runlevel):
    """
    adds users declared in nest_config to the nest_users table
    if they don't already exist
    """

    db_client_maker = core_db.get_nest_users_sqla_maker()
    md = nest_db.get_global_sqlalchemy_metadata()
    engine = nest_db.get_global_sqlalchemy_engine()
    #note this is a tablelike client, not a NestUser client
    db_client = db_client_maker.get_db_client(engine, md)

    #needs a unique *instance* of system_user to act as 'owner'
    #as we will alter the instance that we add to the table
    db_client.set_requesting_user(core_db.get_system_user())

    user_configs = nest_config.generate_seed_users(project_env, runlevel)

    success = _add_users_from_configs(db_client, user_configs)
    return success
Exemplo n.º 9
0
def list_tables_in_db():
    engine = nest_db.get_global_sqlalchemy_engine()
    qs = """
    select table_catalog, table_schema, table_name, table_type 
    from information_schema.tables 
    where table_schema not in ('pg_catalog', 'information_schema');
    """
    q = engine.execute(qs)
    tables = q.fetchall()
    print("tables from db:")
    if len(tables) == 0:
        print('   <None>')
    for i, tbl in enumerate(tables):
        (c, s, n, t) = tbl
        print(str(i) + '.')
        print('   name    :' + str(n))
        print('   catalog :' + str(c))
        print('   type    :' + str(t))
        print('   schema  :' + str(s))
    return True
Exemplo n.º 10
0
def check_db_connection():
    engine = nest_db.get_global_sqlalchemy_engine()
    md = nest_db.get_global_sqlalchemy_metadata()
    try:
        connection = engine.connect()
        qs = 'select 1'
        q = engine.execute(qs)
        obs = q.first()[0]
        if obs == 1:
            print("'Select 1' returned 1")
            connectable = True
        else:
            print("'Select 1' returned " + str(obs))
            connectable = False
    except Exception as e:
        print('Connecting to DB Failed. Exception: ' + str(e))
        connectable = False
    if not connectable:
        print('config was' + str(nest_db.GLOBAL_SQLA_RESOURCES.config))
    return connectable
Exemplo n.º 11
0
def init_db_client_registry(jcx):
    """
    create a dict of database clients for hello_world project's datatypes.
    put the dictionary in the jcx 'runtime' so that they are accessible as:
    jcx.runtime()['db_clients'][<datatype>]
    """
    #get the 'maker' objects for database tables and clients in
    #the hello_world project
    hw_sqla_makers = hw_db.get_sqla_makers()

    sqla_md = nest_db.get_global_sqlalchemy_metadata()
    engine = nest_db.get_global_sqlalchemy_engine()
    registry = dict()
    for maker in hw_sqla_makers.values():
        nm = maker.get_table_name()
        client = maker.get_db_client(engine, sqla_md)
        #need a user to 'own' any data we write. this gives us
        #the default user for jobs
        jobs_auth.set_db_user(client)
        registry[nm] = client
    jcx.runtime()['db_clients'] = registry
    return
Exemplo n.º 12
0
def set_db_user(db_client):
    """
    similar to 'logging in', sets the requesting_user for a
    database client to the standard user that jobs run under.

    Note this is a NestUser for Nest's data ownership model, this
    is not the postgres user that connects to postgres.
    """
    #FIXME: this is a user that is also hardcoded in flask_config,
    #but we are keeping the flask packages out of the jobs packages
    #so we cut and paste
    users_sqla_maker = core_db.get_nest_users_sqla_maker()
    db_engine = nest_db.get_global_sqlalchemy_engine()
    md = nest_db.get_global_sqlalchemy_metadata()
    users_client = users_sqla_maker.get_db_client(db_engine, md)
    users_client.set_requesting_user(core_db.get_system_user())

    username = '******'
    user_tle = users_client.simple_filter_query({'username':username})[0]
    jobs_user = NestUser.from_tablelike_entry(user_tle)
    db_client.set_requesting_user(jobs_user)
    return
Exemplo n.º 13
0
def add_user(username, password):
    """
    leaves most fields blank except the username and password needed
    to login to the webapp. adds the user to the localhost instance.
    """

    db_client_maker = core_db.get_nest_users_sqla_maker()
    md = nest_db.get_global_sqlalchemy_metadata()
    engine = nest_db.get_global_sqlalchemy_engine()
    #note this is a tablelike client, not a NestUser client
    db_client = db_client_maker.get_db_client(engine, md)

    system_user = core_db.get_system_user()
    db_client.set_requesting_user(system_user)

    schema = nest_users.generate_schema()
    passlib_hash = password_hash.compute_passlib_hash(password)

    nu = NestUser(None,
                  username,
                  None,
                  None,
                  is_superuser=False,
                  passlib_hash=passlib_hash,
                  origin='nest')

    tle = nu.to_tablelike_entry()
    tle = db_client.create_entry(tle)
    if tle is None:
        print('FAILURE ensuring user: '******'ensured user: ' + str(username))
        success = True
        ensure_default_project(NestUser.from_tablelike_entry(tle))
    return success
Exemplo n.º 14
0
def build_authenticator(flask_app, project_env, runlevel):
    users_sqla_maker = core_db.get_nest_users_sqla_maker()
    db_engine = nest_db.get_global_sqlalchemy_engine()
    md = nest_db.get_global_sqlalchemy_metadata()
    users_client = users_sqla_maker.get_db_client(db_engine, md)

    #the authenticator will interact with the local db as the master system_user
    auth_user = core_db.get_system_user()
    users_client.set_requesting_user(auth_user)

    #knoweng uses hubzero to look up user accounts in production
    #all other situations will use user accounts stored in the local db
    use_hubzero = (ProjectEnv.knoweng_instance() == project_env
                   and RunLevel.production_instance() == runlevel)

    if use_hubzero:
        print('registering Hubzero authenticator')
        from nest_py.knoweng.flask.accounts.knoweng_authentication import HubzeroAuthenticationStrategy
        authenticator = HubzeroAuthenticationStrategy(flask_app, users_client)
    else:
        from nest_py.core.flask.accounts.authentication import NativeAuthenticationStrategy

        authenticator = NativeAuthenticationStrategy(flask_app, users_client)
    return authenticator
Exemplo n.º 15
0
def drop_tables_in_db():
    engine = nest_db.get_global_sqlalchemy_engine()
    nest_db.get_global_sqlalchemy_base().metadata.drop_all(engine)
    return True
Exemplo n.º 16
0
def test_sqla_tablelike_lifecycle():
    """
    walks through making a table, making it in the database,
    making an entry, updating, etc, using the nest config
    way of setting things up and crud_db_client
    """
    setup_db()
    sqla_md = nest_db.get_global_sqlalchemy_metadata()
    db_engine = nest_db.get_global_sqlalchemy_engine()

    db_registry = hw_db.get_sqla_makers()
    for tbl_name in db_registry:
        print('db registry: ' + str(tbl_name))
    db_client = db_registry['hello_tablelike'].get_db_client(db_engine, sqla_md)
    sys_user = core_db.get_system_user()
    db_client.set_requesting_user(sys_user)

    db_client.delete_all_entries()

    print('testing create_entry')
    tle_orig = HelloTablelikeDTO(1.1, 2.2, 'x', ['a','a'], [0.0, 0.0], NestId(1), [NestId(4), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()
    print(str(tle_orig))
    tle_updated = db_client.create_entry(tle_orig)
    assert(not tle_updated is None)
    nid = tle_updated.get_nest_id()
    print('generated nid: ' + str(nid))
    assert(not nid is None)

    print('testing read_entry')
    tle_rt = db_client.read_entry(nid)
    print('tle_rt: ' + str(tle_rt))
    print('tle_updated: ' + str(tle_updated))
    assert(tle_rt == tle_updated)

    print('testing update_entry')
    tle_unupdated = tle_rt
    tle_unupdated.set_value('flt_val_0', 22.0)
    tle_updated = db_client.update_entry(tle_unupdated)
    tle_updated_rt = db_client.read_entry(nid)
    assert(tle_updated_rt == tle_updated)

    print('testing delete_entry')
    deleted_nid = db_client.delete_entry(nid)
    assert(deleted_nid == nid)
    fetched_deleted = db_client.read_entry(nid)
    assert(fetched_deleted is None)

    print('testing bulk_create_entries')
    t1 = HelloTablelikeDTO(3.0, 3.3, 'y', ['a','a'], [0.0, 0.0], NestId(5), [NestId(1), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()
    t2 = HelloTablelikeDTO(4.0, 4.4, 'y', ['a','b'], [0.0, 0.0], NestId(5), [NestId(1), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()
    t3 = HelloTablelikeDTO(5.0, 5.5, 'x', ['b','b'], [0.0, 0.0], NestId(5), [NestId(1), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()

    tles = [t1, t2, t3]
    up_tles = db_client.bulk_create_entries(tles, batch_size=2)
    assert(not up_tles is None)
    assert(len(up_tles) == len(tles))
    for (orig_tle, up_tle) in zip(tles, up_tles):
        nid = up_tle.get_nest_id()
        assert(not nid is None)
        rt_tle = db_client.read_entry(nid)
        assert(rt_tle == up_tle)
        for att in ['flt_val_0', 'flt_val_1', 'string_val']:
            assert(orig_tle.get_value(att) == rt_tle.get_value(att))

    print('testing bulk_create_entries_async and simple_filter_query')
    db_client.delete_all_entries()
    t1 = HelloTablelikeDTO(6.0, 6.6, 'x', ['b','b'], [0.0, 0.0], NestId(5), [NestId(1), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()
    t2 = HelloTablelikeDTO(7.0, 7.7, 'z', ['a','b'], [2.0, 0.0], NestId(5), [NestId(1), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()
    t3 = HelloTablelikeDTO(8.0, 8.8, 'z', ['b','a'], [0.0, 3.0], NestId(5), [NestId(1), NestId(2)], {'x':'innerx'}, 5, [6, 7]).to_tablelike_entry()
    tles = [t1, t2, t3]
    print('begin async upload')
    upload_count = db_client.bulk_create_entries_async(tles, batch_size=2)
    print('upload count returned: ' + str(upload_count))

    z_tles = db_client.simple_filter_query({'string_val':'z'})
    for z_tle in z_tles:
        nid = z_tle.get_nest_id()
        assert(not nid is None)
        z_tle.set_nest_id(None) #so we can test equivalence easier
    assert(len(z_tles) == 2)
    assert(t2 in z_tles)
    assert(t3 in z_tles)

    x_tles = db_client.simple_filter_query({'string_val':'x', 'flt_val_0':6.0})

    for x_tle in x_tles:
        nid = x_tle.get_nest_id()
        assert(not nid is None)
        x_tle.set_nest_id(None) #so we can test equivalence easier
    assert(len(x_tles) == 1)
    assert(t1 in x_tles)

    print("testing filter by json attribute. should work b/c it's string matching in the db")
    json_tles = db_client.simple_filter_query({'json_val':json.dumps({'x':'innerx'})})
    assert(len(json_tles) == 3)
#
#    print('testing ensure_entry')
#    tK = HelloTablelikeDTO(9.0, 9.9, 'z', ['b','a'], [0.0, 3.0], NestId(5), [NestId(1), NestId(2)], {u'x':u'innerx'}).to_tablelike_entry()
#    tk2 = db_client.ensure_entry(tK)
#    tk3 = db_client.ensure_entry(tK)
#    assert(tk2.get_nest_id() == tk3.get_nest_id())
#    
    db_client.get_sqla_connection().close()
    return