Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tests]: Add new access service #1939

Merged
merged 59 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
98be0e0
[Tests]: Add new access service
Sep 2, 2024
02f4d79
Move access service binaries to service
Sep 2, 2024
cac842c
Delete access service
Sep 3, 2024
4af50d9
TMP save progress
Sep 9, 2024
6132251
Change directory structure according to perviously used
jkuradobery Sep 20, 2024
57df95a
Add http control api to add new accounts to access service mock
jkuradobery Sep 20, 2024
15c0535
Move all the mock code into main.go
jkuradobery Sep 20, 2024
63d7712
Make ssl optional in the recipe
jkuradobery Sep 20, 2024
558fc4b
Add create_account method for AccessServiceLauncher
jkuradobery Sep 20, 2024
4cb8ddc
Allow usage of new access service in nbs tests
jkuradobery Sep 20, 2024
3aec1e3
Rename NewAccessServiceLauncher to NewAccessService
jkuradobery Sep 20, 2024
a60824e
Introduce test for new access service
jkuradobery Sep 20, 2024
7a2cef4
Fix ya.make
jkuradobery Sep 21, 2024
51b68dc
Fix style, fix attribute error
jkuradobery Sep 21, 2024
94ebfba
Fix client config creation
jkuradobery Sep 21, 2024
93e26a5
Fix binary paths
jkuradobery Sep 21, 2024
f990e1f
Add assertions, use secure port in the test
jkuradobery Sep 21, 2024
b198a0e
Add missing schema for http request
jkuradobery Sep 21, 2024
dab3a52
Fix broken test_load()
jkuradobery Sep 21, 2024
635b15c
Fix broken test_new_auth_authorization_ok()
jkuradobery Sep 21, 2024
7c35a9b
Fix flake8
jkuradobery Sep 21, 2024
5c2da66
Pass IAM token through env variable
jkuradobery Sep 21, 2024
03fab29
Remove failing test_auth_unauthenticated()
jkuradobery Sep 21, 2024
722ba16
Rename access_service_nebius -> access_service_new
jkuradobery Sep 23, 2024
0c46230
Remove explicit assignment to server.ServerConfig.StrictContractValid…
jkuradobery Sep 23, 2024
49262eb
Add JsonOutput flag to blockstoreclient createVolume command
jkuradobery Sep 23, 2024
b3bc194
Use library/cpp/json for FormatErrorJson()
jkuradobery Sep 23, 2024
4e23343
Add auth token to the NfsCliClient
jkuradobery Sep 23, 2024
74ba520
Rename recipe directory, use the same env variable for both access se…
jkuradobery Sep 23, 2024
4615695
Make access_service_type a static field member instead of a property
jkuradobery Sep 23, 2024
974a5de
Add access_service_type parameter to the NfsDaemonConfigGenerator
jkuradobery Sep 23, 2024
f4db8ed
Use access service type in service-kikimr filestore recipe
jkuradobery Sep 23, 2024
96a5d81
Add the folder id to the test env variable
jkuradobery Sep 23, 2024
efbfb34
Fix ya.makes
jkuradobery Sep 24, 2024
c08ac2a
Rename ACCESS_SERVICE_VERSION -> ACCESS_SERVICE_TYPE
jkuradobery Sep 24, 2024
0f94f58
Fix ya.make peerdir
jkuradobery Sep 24, 2024
441a3a1
Fix review discussions
jkuradobery Sep 24, 2024
fc7ced6
Fix review discussions
jkuradobery Sep 24, 2024
eef1706
Return subprocess.Result in NfsCliClient.create()
jkuradobery Sep 24, 2024
bdfb726
Introduce auth tests for the filestore
jkuradobery Sep 24, 2024
56ae5e8
User recipe even without test token
jkuradobery Sep 25, 2024
712e19a
Add config, use secure port for auth tests
jkuradobery Sep 25, 2024
960d21e
Use correct recipes for new access service
jkuradobery Sep 25, 2024
1bdde02
Use client config, Fix TLS
jkuradobery Sep 25, 2024
b76a922
Add logs in new access service mock
jkuradobery Sep 25, 2024
329b31b
Fix review discussions
jkuradobery Sep 25, 2024
554f984
Fix review discussions
jkuradobery Sep 25, 2024
fb364a1
Fix review discussions
jkuradobery Sep 25, 2024
2c8e4d4
Print error json in filestoreclient.create
jkuradobery Sep 25, 2024
bedd487
Fix permissions in filestore auth test
jkuradobery Sep 25, 2024
68b8d4c
Use json filestore client output in test
jkuradobery Sep 25, 2024
5612445
Fix filestore auth test hanging
jkuradobery Sep 25, 2024
55e9a51
Fix style, add comments
jkuradobery Sep 25, 2024
9b2f732
Replace test_auth_wrong_token() with test_auth_empty_token()
jkuradobery Sep 25, 2024
5325004
Remove set RetryTimeout to 1 in tests
jkuradobery Sep 25, 2024
f3ce706
Fix review discussions
jkuradobery Sep 25, 2024
78c5f7e
Remove pid check
jkuradobery Sep 26, 2024
a306c57
Remove test_auth_empty_token()
jkuradobery Sep 26, 2024
ee0ada5
Fix flake8
jkuradobery Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cloud/blockstore/apps/client/lib/create_volume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cloud/storage/core/libs/common/error.h>
#include <cloud/storage/core/libs/diagnostics/logging.h>

#include <library/cpp/json/json_writer.h>
#include <library/cpp/protobuf/util/pb_io.h>

namespace NCloud::NBlockStore::NClient {
Expand Down Expand Up @@ -47,6 +48,7 @@ class TCreateVolumeCommand final

TString StoragePoolName;
TVector<TString> AgentIds;
bool JsonOutput = false;

public:
TCreateVolumeCommand(IBlockStorePtr client)
Expand Down Expand Up @@ -116,6 +118,7 @@ class TCreateVolumeCommand final
"Allowed only for nonreplicated disks")
.RequiredArgument("STR")
.AppendTo(&AgentIds);
Opts.AddLongOption("json").StoreTrue(&JsonOutput);
}

protected:
Expand Down Expand Up @@ -179,6 +182,18 @@ class TCreateVolumeCommand final
return true;
}

if (JsonOutput){
// We don't use result.PrintJSON(), because TError.PrintJSON()
// writes only code, and it is more reliable to use formatted
// error in tests and scripts.
NJson::TJsonValue resultJson;
if (HasError(result)){
resultJson["Error"] = FormatErrorJson(result.GetError());
}
NJson::WriteJson(&output, &resultJson, false, true, true);
return !HasError(result);
}

if (HasError(result)) {
output << FormatError(result.GetError()) << Endl;
return false;
Expand Down
172 changes: 167 additions & 5 deletions cloud/blockstore/tests/loadtest/local-auth/test.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import json
import logging
import subprocess

import yatest.common as common

from cloud.blockstore.config.client_pb2 import TClientConfig
from pathlib import Path

from google.protobuf.text_format import MessageToString

from cloud.blockstore.config.client_pb2 import TClientAppConfig, TClientConfig
from cloud.blockstore.config.server_pb2 import TServerAppConfig, TServerConfig, TKikimrServiceConfig
from cloud.blockstore.config.storage_pb2 import TStorageServiceConfig
from cloud.blockstore.tests.python.lib.loadtest_env import LocalLoadTest
from cloud.blockstore.tests.python.lib.test_base import thread_count, run_test
from cloud.storage.core.protos.authorization_mode_pb2 import EAuthorizationMode
from cloud.storage.core.tools.testing.access_service.lib import AccessService
from cloud.storage.core.tools.testing.access_service_new.lib import NewAccessService


def test_load():
def create_server_app_config():
server = TServerAppConfig()
server.ServerConfig.CopyFrom(TServerConfig())
server.ServerConfig.ThreadsCount = thread_count()
server.ServerConfig.StrictContractValidation = False
server.ServerConfig.RootCertsFile = common.source_path(
"cloud/blockstore/tests/certs/server.crt")
cert = server.ServerConfig.Certs.add()
Expand All @@ -21,10 +29,21 @@ def test_load():
cert.CertPrivateKeyFile = common.source_path(
"cloud/blockstore/tests/certs/server.key")
server.KikimrServiceConfig.CopyFrom(TKikimrServiceConfig())
return server


def create_storage_service_config(folder_id="test_folder_id"):
storage = TStorageServiceConfig()
storage.AuthorizationMode = EAuthorizationMode.Value("AUTHORIZATION_REQUIRE")
storage.FolderId = "test_folder_id"
storage.FolderId = folder_id
return storage


def test_load():
server = create_server_app_config()
server.ServerConfig.ThreadsCount = thread_count()

storage = create_storage_service_config("test_folder_id")

env = LocalLoadTest(
"",
Expand Down Expand Up @@ -58,3 +77,146 @@ def test_load():
env.tear_down()

return ret


def create_client_config():
client = TClientAppConfig()
client.ClientConfig.CopyFrom(TClientConfig())
client.ClientConfig.RootCertsFile = common.source_path(
"cloud/blockstore/tests/certs/server.crt")
return client


class TestFixture:
__binary_path = common.binary_path("cloud/blockstore/apps/client/blockstore-client")

def __init__(self, access_service_type=AccessService, folder_id="test_folder_id"):
server = create_server_app_config()
storage = create_storage_service_config(folder_id)
self.__local_load_test = LocalLoadTest(
"",
server_app_config=server,
enable_access_service=True,
storage_config_patches=[storage],
enable_tls=True,
use_in_memory_pdisks=True,
access_service_type=access_service_type,
)
self.__client_config_path = Path(common.output_path()) / "client-config.txt"
self.__client_config = create_client_config()
self.__client_config.ClientConfig.SecurePort = self.__local_load_test.nbs_secure_port
self.__client_config_path.write_text(MessageToString(self.__client_config))
self.folder_id = folder_id
self.__auth_token = None

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.__local_load_test.tear_down()

def run(self, *args, **kwargs):
args = [self.__binary_path, *args, "--config", str(self.__client_config_path)]

env = {}
if self.__auth_token is not None:
env['IAM_TOKEN'] = self.__auth_token
logging.info("running command: %s" % args)
result = subprocess.run(
args,
cwd=kwargs.get("cwd"),
check=False,
capture_output=True,
text=True,
env=env,
)
return result

def create_volume(self):
result = self.run("createvolume", "--disk-id", "vol0", "--blocks-count", "25000", "--json")
logging.info("Disk creation stdout: %s, stderr: %s", result.stdout, result.stderr)
return result

@property
def access_service(self):
return self.__local_load_test.access_service

def set_auth_token(self, token: str):
self.__auth_token = token


def test_auth_unauthorized():
with TestFixture() as env:
token = "test_auth_token"
env.set_auth_token(token)
env.access_service.authenticate(token)
result = env.create_volume()
assert result.returncode != 0
assert json.loads(result.stdout)["Error"]["CodeString"] == "E_UNAUTHORIZED"


def test_auth_empty_token():
with TestFixture() as env:
env.set_auth_token("")
env.access_service.authorize("test_auth_token")
result = env.create_volume()
assert result.returncode != 0
assert json.loads(result.stdout)["Error"]["CodeString"] == "E_UNAUTHORIZED"


def test_new_auth_authorization_ok():
with TestFixture(NewAccessService) as env:
token = "test_auth_token"
env.set_auth_token(token)
env.access_service.create_account(
token,
token,
is_unknown_subject=False,
permissions=[
{"permission": "nbsInternal.disks.create", "resource": env.folder_id},
],
)
result = env.create_volume()
assert result.returncode == 0


def test_new_auth_unauthorized():
with TestFixture(NewAccessService) as env:
token = "test_auth_token"
env.set_auth_token(token)
env.access_service.create_account(
"test_user",
token,
is_unknown_subject=False,
permissions=[
{"permission": "nbsInternal.disks.create", "resource": "some_other_folder"},
],
)
result = env.create_volume()
assert result.returncode != 0
assert json.loads(result.stdout)["Error"]["CodeString"] == "E_UNAUTHORIZED"


def test_new_auth_unauthenticated():
with TestFixture(NewAccessService) as env:
env.set_auth_token("some_other_token")
result = env.create_volume()
assert result.returncode != 0
assert json.loads(result.stdout)["Error"]["CodeString"] == "E_UNAUTHORIZED"
SvartMetal marked this conversation as resolved.
Show resolved Hide resolved


def test_new_auth_unknown_subject():
with TestFixture(NewAccessService) as env:
token = "test_token"
env.set_auth_token(token)
env.access_service.create_account(
"test_user",
token,
is_unknown_subject=True,
permissions=[
{"permission": "nbsInternal.disks.create", "resource": env.folder_id},
],
)
result = env.create_volume()
assert result.returncode != 0
assert json.loads(result.stdout)["Error"]["CodeString"] == "E_UNAUTHORIZED"
1 change: 1 addition & 0 deletions cloud/blockstore/tests/loadtest/local-auth/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ TEST_SRCS(

DEPENDS(
cloud/storage/core/tools/testing/access_service/mock
cloud/storage/core/tools/testing/access_service_new/mock
)

DATA(
Expand Down
6 changes: 5 additions & 1 deletion cloud/blockstore/tests/python/lib/loadtest_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
setup_disk_registry_proxy_config, setup_disk_agent_config

from cloud.blockstore.tests.python.lib.test_base import wait_for_nbs_server
from cloud.storage.core.tools.testing.access_service.lib import AccessService

from .nbs_runner import LocalNbs
from .endpoint_proxy import EndpointProxy
Expand Down Expand Up @@ -51,6 +52,7 @@ def __init__(
kikimr_binary_path=None,
with_endpoint_proxy=False,
with_netlink=False,
access_service_type=AccessService,
load_configs_from_cms=True,
):

Expand Down Expand Up @@ -113,7 +115,9 @@ def __init__(
load_configs_from_cms=load_configs_from_cms,
features_config_patch=features_config_patch,
grpc_trace=grpc_trace,
rack=rack)
rack=rack,
access_service_type=access_service_type,
)

self.endpoint_proxy = None
if with_endpoint_proxy:
Expand Down
8 changes: 6 additions & 2 deletions cloud/blockstore/tests/python/lib/nbs_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ def __init__(
rack="the_rack",
use_ic_version_check=False,
use_secure_registration=False,
grpc_ssl_port=None):
grpc_ssl_port=None,
access_service_type=AccessService,
):

if dynamic_storage_pools is not None:
assert len(dynamic_storage_pools) >= 2
Expand Down Expand Up @@ -149,7 +151,8 @@ def __init__(
host = "localhost"
port = self.__port_manager.get_port()
control_server_port = self.__port_manager.get_port()
self.__access_service = AccessService(host, port, control_server_port)
self._access_service_type = access_service_type
self.__access_service = self._access_service_type(host, port, control_server_port)
self.__proto_configs["auth.txt"] = self.__generate_auth_txt(port)

self.__load_configs_from_cms = load_configs_from_cms
Expand Down Expand Up @@ -410,6 +413,7 @@ def __generate_auth_txt(self, port):
auth_config.UseBlackBox = False
auth_config.UseStaff = False
auth_config.AccessServiceEndpoint = "localhost:{}".format(port)
auth_config.AccessServiceType = self.__access_service.access_service_type
return auth_config

def __generate_dr_proxy_txt(self):
Expand Down
1 change: 1 addition & 0 deletions cloud/blockstore/tests/python/lib/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ PEERDIR(

cloud/storage/core/tools/common/python
cloud/storage/core/tools/testing/access_service/lib
cloud/storage/core/tools/testing/access_service_new/lib
cloud/storage/core/tools/testing/qemu/lib

contrib/ydb/core/protos
Expand Down
21 changes: 21 additions & 0 deletions cloud/filestore/apps/client/lib/create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "performance_profile_params.h"

#include "library/cpp/json/json_writer.h"

#include <cloud/filestore/public/api/protos/fs.pb.h>

#include <util/generic/size_literals.h>
Expand Down Expand Up @@ -86,6 +88,25 @@ class TCreateCommand final
std::move(callContext),
std::move(request)));

if (JsonOutput){
// We don't use result.PrintJSON(), because TError.PrintJSON()
// writes only code, and it is more reliable to use formatted
// error in tests and scripts.
NJson::TJsonValue resultJson;
if (HasError(response)){
resultJson["Error"] = FormatErrorJson(response.GetError());
}

NJson::WriteJson(&Cout, &resultJson, false, true, true);

if (HasError(response)){
ProgramShouldContinue.ShouldStop(1);
return false;
}

return true;
}

if (HasError(response)) {
ythrow TServiceError(response.GetError());
}
Expand Down
Loading
Loading