Esempio n. 1
0
def wipe(*, postgres_dsn, data_dir, yes, dry_run):
    if postgres_dsn:
        cluster = pgcluster.get_remote_pg_cluster(postgres_dsn)
    elif data_dir:
        cluster = pgcluster.get_local_pg_cluster(data_dir)
        cluster.set_connection_params(
            pgconnparams.ConnectionParameters(
                user='******',
                database='template1',
            ), )
    else:
        raise click.UsageError(
            'either --postgres-dsn or --data-dir is required')

    if not yes and not click.confirm(
            'This will DELETE all EdgeDB data from the target '
            'PostgreSQL instance.  ARE YOU SURE?'):
        click.echo('OK. Not proceeding.')

    status = cluster.get_status()
    cluster_started_by_us = False
    if status != 'running':
        if isinstance(cluster, pgcluster.RemoteCluster):
            click.secho(f'Remote cluster is not running', fg='red')
            sys.exit(1)
        else:
            cluster.start(port=edbcluster.find_available_port())
            cluster_started_by_us = True

    try:
        asyncio.run(do_wipe(cluster, dry_run))
    finally:
        if cluster_started_by_us:
            cluster.stop()
Esempio n. 2
0
 async def test_server_ops_ignore_other_tenants_single_role(self):
     with tempfile.TemporaryDirectory() as td:
         cluster = await pgcluster.get_local_pg_cluster(td, log_level='s')
         cluster.set_connection_params(
             pgconnparams.ConnectionParameters(
                 user='******',
                 database='template1',
             ), )
         self.assertTrue(await cluster.ensure_initialized())
         cluster.add_hba_entry(
             type="local",
             database="all",
             user="******",
             auth_method="trust",
         )
         await cluster.start()
         conn = await cluster.connect()
         setup = """\
             CREATE ROLE single WITH LOGIN CREATEDB;
             CREATE DATABASE single;
             REVOKE ALL ON DATABASE single FROM PUBLIC;
             GRANT CONNECT ON DATABASE single TO single;
             GRANT ALL ON DATABASE single TO single;\
         """
         for sql in setup.split('\n'):
             await conn.execute(sql)
         await conn.close()
         try:
             await self._test_server_ops_ignore_other_tenants(td, 'single')
         finally:
             await cluster.stop()
Esempio n. 3
0
    def test_server_ops_postgres_recovery(self):
        async def test(pgdata_path):
            async with tb.start_edgedb_server(
                    postgres_dsn=
                    f'postgres:///?user=postgres&host={pgdata_path}',
                    reset_auth=True,
                    runstate_dir=None
                    if devmode.is_in_dev_mode() else pgdata_path,
            ) as sd:
                con = await sd.connect()
                try:
                    val = await con.query_single('SELECT 123')
                    self.assertEqual(int(val), 123)

                    # stop the postgres
                    cluster.stop()
                    # TODO: Use BackendUnavailableError here, same below
                    with self.assertRaisesRegex(
                            errors.EdgeDBError,
                            'Postgres is not available',
                    ):
                        await con.query_single('SELECT 123+456')

                    # bring postgres back
                    await self.loop.run_in_executor(None, cluster.start)

                    # give the EdgeDB server some time to recover
                    deadline = time.monotonic() + 5
                    while time.monotonic() < deadline:
                        try:
                            val = await con.query_single('SELECT 123+456')
                            break
                        except errors.EdgeDBError:  # TODO: ditto
                            pass
                    self.assertEqual(int(val), 579)
                finally:
                    await con.aclose()

        with tempfile.TemporaryDirectory() as td:
            cluster = pgcluster.get_local_pg_cluster(td, log_level='s')
            cluster.set_connection_params(
                pgconnparams.ConnectionParameters(
                    user='******',
                    database='template1',
                ), )
            self.assertTrue(cluster.ensure_initialized())
            cluster.start()
            try:
                self.loop.run_until_complete(test(td))
            finally:
                cluster.stop()
Esempio n. 4
0
    async def test_server_ops_ignore_other_tenants(self):
        with tempfile.TemporaryDirectory() as td:
            cluster = await pgcluster.get_local_pg_cluster(td, log_level='s')
            cluster.set_connection_params(
                pgconnparams.ConnectionParameters(
                    user='******',
                    database='template1',
                ), )
            self.assertTrue(await cluster.ensure_initialized())

            await cluster.start()
            try:
                await self._test_server_ops_ignore_other_tenants(
                    td, 'postgres')
            finally:
                await cluster.stop()
Esempio n. 5
0
    def test_server_ops_postgres_multitenant(self):
        async def test(pgdata_path, tenant):
            async with tb.start_edgedb_server(
                    auto_shutdown=True,
                    tenant_id=tenant,
                    reset_auth=True,
                    postgres_dsn=
                    f'postgres:///?user=postgres&host={pgdata_path}',
                    runstate_dir=None
                    if devmode.is_in_dev_mode() else pgdata_path,
            ) as sd:
                con = await sd.connect()
                try:
                    await con.execute(f'CREATE DATABASE {tenant}')
                    await con.execute(f'CREATE SUPERUSER ROLE {tenant}')
                    databases = await con.query('SELECT sys::Database.name')
                    self.assertEqual(set(databases), {'edgedb', tenant})
                    roles = await con.query('SELECT sys::Role.name')
                    self.assertEqual(set(roles), {'edgedb', tenant})
                finally:
                    await con.aclose()

        async def run():
            async with taskgroup.TaskGroup() as tg:
                tg.create_task(test(td, 'tenant1'))
                tg.create_task(test(td, 'tenant2'))

        with tempfile.TemporaryDirectory() as td:
            cluster = pgcluster.get_local_pg_cluster(td)
            cluster.set_connection_params(
                pgconnparams.ConnectionParameters(
                    user='******',
                    database='template1',
                ), )
            self.assertTrue(cluster.ensure_initialized())
            cluster.start()
            try:
                self.loop.run_until_complete(run())
            finally:
                cluster.stop()
Esempio n. 6
0
    def test_server_ops_detect_postgres_pool_size(self):
        port = edgedb_cluster.find_available_port()
        actual = random.randint(50, 100)

        async def test(host):
            bootstrap_command = (
                r'CONFIGURE SYSTEM INSERT Auth '
                r'{ priority := 0, method := (INSERT Trust) }')
            async with tb.start_edgedb_server(
                    auto_shutdown=True,
                    bootstrap_command=bootstrap_command,
                    max_allowed_connections=None,
                    postgres_dsn=f'postgres:///?user=postgres&port={port}&'
                    f'host={host}',
            ) as sd:
                con = await edgedb.async_connect(user='******',
                                                 host=sd.host,
                                                 port=sd.port)
                try:
                    max_connections = await con.query_one(
                        'SELECT cfg::SystemConfig.__pg_max_connections '
                        'LIMIT 1')  # TODO: remove LIMIT 1 after #2402
                    self.assertEqual(int(max_connections), actual)
                finally:
                    await con.aclose()

        with tempfile.TemporaryDirectory() as td:
            cluster = pgcluster.get_local_pg_cluster(td,
                                                     max_connections=actual)
            cluster.set_connection_params(
                pgconnparams.ConnectionParameters(
                    user='******',
                    database='template1',
                ), )
            self.assertTrue(cluster.ensure_initialized())
            cluster.start(port=port)
            try:
                self.loop.run_until_complete(test(td))
            finally:
                cluster.stop()
Esempio n. 7
0
    def test_server_ops_detect_postgres_pool_size(self):
        actual = random.randint(50, 100)

        async def test(pgdata_path):
            async with tb.start_edgedb_server(
                    auto_shutdown=True,
                    max_allowed_connections=None,
                    postgres_dsn=
                    f'postgres:///?user=postgres&host={pgdata_path}',
                    reset_auth=True,
                    runstate_dir=None
                    if devmode.is_in_dev_mode() else pgdata_path,
            ) as sd:
                con = await sd.connect()
                try:
                    max_connections = await con.query_single(
                        '''
                        SELECT cfg::InstanceConfig.__pg_max_connections
                        LIMIT 1
                        ''')  # TODO: remove LIMIT 1 after #2402
                    self.assertEqual(int(max_connections), actual)
                finally:
                    await con.aclose()

        with tempfile.TemporaryDirectory() as td:
            cluster = pgcluster.get_local_pg_cluster(td,
                                                     max_connections=actual,
                                                     log_level='s')
            cluster.set_connection_params(
                pgconnparams.ConnectionParameters(
                    user='******',
                    database='template1',
                ), )
            self.assertTrue(cluster.ensure_initialized())
            cluster.start()
            try:
                self.loop.run_until_complete(test(td))
            finally:
                cluster.stop()