@@ -1306,6 +1306,8 @@ def setup_class(cls):
1306
1306
"enable_database_admin"
1307
1307
],
1308
1308
domain_login_only = False ,
1309
+ enforce_user_token_requirement = True ,
1310
+ default_clusteradmin = "root@builtin" ,
1309
1311
))
1310
1312
cls .cluster .start ()
1311
1313
@@ -1317,15 +1319,17 @@ def setup_class(cls):
1317
1319
storage_pool_units_count = {
1318
1320
'hdd' : 1
1319
1321
},
1320
- timeout_seconds = 100
1322
+ timeout_seconds = 100 ,
1323
+ token = cls .cluster .config .default_clusteradmin
1321
1324
)
1322
1325
1323
1326
cls .database_nodes = cls .cluster .register_and_start_slots (cls .database , count = 3 )
1324
- cls .cluster .wait_tenant_up (cls .database )
1327
+ cls .cluster .wait_tenant_up (cls .database , cls . cluster . config . default_clusteradmin )
1325
1328
1326
1329
driver_config = ydb .DriverConfig (
1327
1330
database = cls .database ,
1328
- endpoint = "%s:%s" % (cls .cluster .nodes [1 ].host , cls .cluster .nodes [1 ].port ))
1331
+ endpoint = "%s:%s" % (cls .cluster .nodes [1 ].host , cls .cluster .nodes [1 ].port ),
1332
+ credentials = ydb .AuthTokenCredentials (cls .cluster .config .default_clusteradmin ))
1329
1333
cls .driver = ydb .Driver (driver_config )
1330
1334
cls .driver .wait (timeout = 4 )
1331
1335
@@ -1340,8 +1344,8 @@ def set_test_name(cls, request):
1340
1344
cls .test_name = request .node .name
1341
1345
1342
1346
@classmethod
1343
- def create_backup (cls , command , expected_files , additional_args = []):
1344
- backup_files_dir = output_path (cls .test_name , "backup_files_dir" )
1347
+ def create_backup (cls , command , expected_files , output , additional_args = [], token = "" ):
1348
+ backup_files_dir = output_path (cls .test_name , output )
1345
1349
execution = yatest .common .execute (
1346
1350
[
1347
1351
backup_bin (),
@@ -1350,7 +1354,8 @@ def create_backup(cls, command, expected_files, additional_args=[]):
1350
1354
]
1351
1355
+ command
1352
1356
+ ["--output" , backup_files_dir ]
1353
- + additional_args
1357
+ + additional_args ,
1358
+ env = {"YDB_TOKEN" : token }
1354
1359
)
1355
1360
1356
1361
list_result = fs_recursive_list (backup_files_dir , ListMode .FILES )
@@ -1370,32 +1375,59 @@ def create_backup(cls, command, expected_files, additional_args=[]):
1370
1375
)
1371
1376
1372
1377
@classmethod
1373
- def create_cluster_backup (cls , expected_files , additional_args = []):
1378
+ def create_cluster_backup (cls , expected_files , output = "backup_files_dir" , additional_args = []):
1374
1379
cls .create_backup (
1375
1380
[
1376
1381
"--database" , cls .root_dir ,
1377
1382
"admin" , "cluster" , "dump" ,
1378
1383
],
1379
1384
expected_files ,
1380
- additional_args
1385
+ output ,
1386
+ additional_args ,
1387
+ token = cls .cluster .config .default_clusteradmin ,
1381
1388
)
1382
1389
1383
1390
@classmethod
1384
- def create_database_backup (cls , expected_files , additional_args = []):
1391
+ def create_database_backup (cls , expected_files , output = "backup_files_dir" , additional_args = []):
1385
1392
cls .create_backup (
1386
1393
[
1387
1394
"--database" , cls .database ,
1395
+ "--user" , "dbadmin1" , "--no-password" ,
1388
1396
"admin" , "database" , "dump" ,
1389
1397
],
1390
1398
expected_files ,
1399
+ output ,
1391
1400
additional_args
1392
1401
)
1393
1402
1403
+ @classmethod
1404
+ def setup_sample_data (cls ):
1405
+ pool = ydb .SessionPool (cls .driver )
1406
+ with pool .checkout () as session :
1407
+ session .execute_scheme ("CREATE GROUP people" )
1408
+ session .execute_scheme ("CREATE USER alice PASSWORD '1234'" )
1409
+ session .execute_scheme ("CREATE USER bob PASSWORD '1234'" )
1410
+ session .execute_scheme ("ALTER GROUP people ADD USER alice" )
1411
+ session .execute_scheme ("ALTER GROUP people ADD USER bob" )
1412
+
1413
+ session .execute_scheme ("CREATE GROUP dbadmins" )
1414
+ session .execute_scheme ("CREATE USER dbadmin1" )
1415
+ session .execute_scheme ("CREATE USER dbadmin2 PASSWORD '1234'" )
1416
+ session .execute_scheme ("ALTER GROUP dbadmins ADD USER dbadmin1" )
1417
+ session .execute_scheme ("ALTER GROUP dbadmins ADD USER dbadmin2" )
1418
+ session .execute_scheme (f'GRANT "ydb.generic.use" on `{ cls .database } ` TO dbadmins' )
1419
+
1420
+ cls .driver .scheme_client .modify_permissions (
1421
+ cls .database ,
1422
+ ydb .ModifyPermissionsSettings ().change_owner ("dbadmins" )
1423
+ )
1424
+
1425
+ create_table_with_data (cls .driver .table_client .session ().create (), "db1/table" )
1426
+
1394
1427
1395
1428
class TestClusterBackup (BaseTestClusterBackupInFiles ):
1396
1429
def test_cluster_backup (self ):
1397
- session = self .driver .table_client .session ().create ()
1398
- create_table_with_data (session , "db1/table" )
1430
+ self .setup_sample_data ()
1399
1431
1400
1432
self .create_cluster_backup (expected_files = [
1401
1433
# cluster metadata
@@ -1415,8 +1447,7 @@ def test_cluster_backup(self):
1415
1447
1416
1448
class TestDatabaseBackup (BaseTestClusterBackupInFiles ):
1417
1449
def test_database_backup (self ):
1418
- session = self .driver .table_client .session ().create ()
1419
- create_table_with_data (session , "db1/table" )
1450
+ self .setup_sample_data ()
1420
1451
1421
1452
self .create_database_backup (expected_files = [
1422
1453
# database metadata
@@ -1431,3 +1462,162 @@ def test_database_backup(self):
1431
1462
"table/permissions.pb" ,
1432
1463
"table/data_00.csv" ,
1433
1464
])
1465
+
1466
+
1467
+ class BaseTestMultipleClusterBackupInFiles (BaseTestClusterBackupInFiles ):
1468
+ @classmethod
1469
+ def setup_class (cls ):
1470
+ super ().setup_class ()
1471
+
1472
+ cfg = KikimrConfigGenerator (
1473
+ extra_feature_flags = [
1474
+ "enable_strict_acl_check" ,
1475
+ "enable_strict_user_management" ,
1476
+ "enable_database_admin"
1477
+ ],
1478
+ domain_name = "Root2" ,
1479
+ domain_login_only = False ,
1480
+ enforce_user_token_requirement = True ,
1481
+ default_clusteradmin = "root@builtin" ,
1482
+ )
1483
+
1484
+ cls .restore_cluster = KiKiMR (
1485
+ cfg ,
1486
+ cluster_name = "restore_cluster"
1487
+ )
1488
+
1489
+ cls .restore_cluster .start ()
1490
+
1491
+ cls .restore_root_dir = "/Root2"
1492
+ cls .restore_database = os .path .join (cls .restore_root_dir , "db1" )
1493
+ cls .restore_database_nodes = cls .restore_cluster .register_and_start_slots (
1494
+ cls .restore_database ,
1495
+ count = 1
1496
+ )
1497
+
1498
+ restore_driver_config = ydb .DriverConfig (
1499
+ database = cls .restore_database ,
1500
+ endpoint = "%s:%s" % (
1501
+ cls .restore_cluster .nodes [1 ].host ,
1502
+ cls .restore_cluster .nodes [1 ].port
1503
+ ),
1504
+ credentials = ydb .AuthTokenCredentials (cls .cluster .config .default_clusteradmin ),
1505
+ )
1506
+ cls .restore_driver = ydb .Driver (restore_driver_config )
1507
+
1508
+ @classmethod
1509
+ def teardown_class (cls ):
1510
+ cls .restore_cluster .unregister_and_stop_slots (cls .restore_database_nodes )
1511
+ cls .restore_cluster .stop ()
1512
+ super ().teardown_class ()
1513
+
1514
+ @classmethod
1515
+ def restore (cls , command , input , additional_args = [], token = "" ):
1516
+ backup_files_dir = os .path .join (
1517
+ yatest .common .output_path (),
1518
+ cls .test_name ,
1519
+ input
1520
+ )
1521
+
1522
+ yatest .common .execute (
1523
+ [
1524
+ backup_bin (),
1525
+ "--verbose" ,
1526
+ "--assume-yes" ,
1527
+ "--endpoint" , f"grpc://localhost:{ cls .restore_cluster .nodes [1 ].grpc_port } " ,
1528
+ ]
1529
+ + command
1530
+ + ["--input" , backup_files_dir , "-w" , "60s" ]
1531
+ + additional_args ,
1532
+ env = {"YDB_TOKEN" : token }
1533
+ )
1534
+
1535
+ @classmethod
1536
+ def restore_cluster_backup (cls , input = "backup_files_dir" , additional_args = []):
1537
+ cls .restore (
1538
+ [
1539
+ "--database" , cls .restore_root_dir ,
1540
+ "admin" , "cluster" , "restore"
1541
+ ],
1542
+ input ,
1543
+ additional_args ,
1544
+ token = cls .restore_cluster .config .default_clusteradmin ,
1545
+ )
1546
+
1547
+ @classmethod
1548
+ def restore_database_backup (cls , input = "backup_files_dir" , additional_args = []):
1549
+ cls .restore (
1550
+ [
1551
+ "--database" , cls .restore_database ,
1552
+ "--user" , "dbadmin1" , "--no-password" ,
1553
+ "admin" , "database" , "restore"
1554
+ ],
1555
+ input ,
1556
+ additional_args
1557
+ )
1558
+
1559
+
1560
+ class TestClusterBackupRestore (BaseTestMultipleClusterBackupInFiles ):
1561
+ def test_cluster_backup_restore (self ):
1562
+ self .setup_sample_data ()
1563
+
1564
+ self .create_cluster_backup (expected_files = [
1565
+ # cluster metadata
1566
+ "permissions.pb" ,
1567
+ "create_user.sql" ,
1568
+ "create_group.sql" ,
1569
+ "alter_group.sql" ,
1570
+
1571
+ # database metadata
1572
+ "Root/db1/database.pb" ,
1573
+ "Root/db1/permissions.pb" ,
1574
+ "Root/db1/create_user.sql" ,
1575
+ "Root/db1/create_group.sql" ,
1576
+ "Root/db1/alter_group.sql" ,
1577
+ ])
1578
+
1579
+ self .restore_cluster_backup ()
1580
+
1581
+ self .restore_cluster .wait_tenant_up (self .restore_database , self .cluster .config .default_clusteradmin )
1582
+ self .restore_driver .wait (timeout = 10 )
1583
+
1584
+
1585
+ class TestDatabaseBackupRestore (BaseTestMultipleClusterBackupInFiles ):
1586
+ def test_database_backup_restore (self ):
1587
+ self .setup_sample_data ()
1588
+
1589
+ self .create_cluster_backup (output = "cluster_backup" , expected_files = [
1590
+ # cluster metadata
1591
+ "permissions.pb" ,
1592
+ "create_user.sql" ,
1593
+ "create_group.sql" ,
1594
+ "alter_group.sql" ,
1595
+
1596
+ # database metadata
1597
+ "Root/db1/database.pb" ,
1598
+ "Root/db1/permissions.pb" ,
1599
+ "Root/db1/create_user.sql" ,
1600
+ "Root/db1/create_group.sql" ,
1601
+ "Root/db1/alter_group.sql" ,
1602
+ ])
1603
+
1604
+ self .create_database_backup (output = "database_backup" , expected_files = [
1605
+ # database metadata
1606
+ "database.pb" ,
1607
+ "permissions.pb" ,
1608
+ "create_user.sql" ,
1609
+ "create_group.sql" ,
1610
+ "alter_group.sql" ,
1611
+
1612
+ # database table
1613
+ "table/scheme.pb" ,
1614
+ "table/permissions.pb" ,
1615
+ "table/data_00.csv" ,
1616
+ ])
1617
+
1618
+ self .restore_cluster_backup (input = "cluster_backup" )
1619
+
1620
+ self .restore_cluster .wait_tenant_up (self .restore_database , self .cluster .config .default_clusteradmin )
1621
+ self .restore_driver .wait (timeout = 10 )
1622
+
1623
+ self .restore_database_backup (input = "database_backup" )
0 commit comments