main/minio_server.py: Respect any preexisting AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY vars

Fixes scylladb/scylla-pkg#3845

Don't overwrite (or rather change) AWS credentials variables if already set in
enclosing environment. Ensures EAR tests for AWS KMS can run properly in CI.

v2:
* Allow environment variables in reading obj storage config - allows CI to
  use real credentials in env without risking putting them info less seure
  files
* Don't write credentials info from miniserver into config, instead use said
  environment vars to propagate creds.

v3:
* Fix python launch scripts to not clear environment, thus retaining above aws envs.

Closes scylladb/scylladb#19086
This commit is contained in:
Calle Wilund
2024-06-04 11:09:48 +00:00
committed by Botond Dénes
parent 73dfa4143a
commit 51c53d8db6
3 changed files with 37 additions and 11 deletions

27
main.cc
View File

@@ -171,12 +171,29 @@ struct convert<::object_storage_endpoint_param> {
ep.endpoint = node["name"].as<std::string>();
ep.config.port = node["port"].as<unsigned>();
ep.config.use_https = node["https"].as<bool>(false);
if (node["aws_region"]) {
if (node["aws_region"] || std::getenv("AWS_DEFAULT_REGION")) {
ep.config.aws.emplace();
ep.config.aws->region = node["aws_region"].as<std::string>();
ep.config.aws->access_key_id = node["aws_access_key_id"].as<std::string>();
ep.config.aws->secret_access_key = node["aws_secret_access_key"].as<std::string>();
ep.config.aws->session_token = node["aws_session_token"].as<std::string>("");
// https://github.com/scylladb/scylla-pkg/issues/3845
// Allow picking up aws values via standard env vars as well.
// Value in config has prio, but fall back to env.
// This has the added benefit of potentially reducing the amount of
// sensitive data in config files (i.e. credentials)
auto get_node_value_or_env = [&](const char* key, const char* var) {
auto child = node[key];
if (child) {
return child.as<std::string>();
}
auto val = std::getenv(var);
if (val) {
return std::string(val);
}
return std::string{};
};
ep.config.aws->region = get_node_value_or_env("aws_region", "AWS_DEFAULT_REGION");
ep.config.aws->access_key_id = get_node_value_or_env("aws_access_key_id", "AWS_ACCESS_KEY_ID");
ep.config.aws->secret_access_key = get_node_value_or_env("aws_secret_access_key", "AWS_SECRET_ACCESS_KEY");
ep.config.aws->session_token = get_node_value_or_env("aws_session_token", "AWS_SESSION_TOKEN");
}
return true;
}

View File

@@ -50,9 +50,10 @@ class MinioServer:
self.default_user = 'minioadmin'
self.default_pass = 'minioadmin'
self.bucket_name = 'testbucket'
self.access_key = ''.join(random.choice(string.hexdigits) for i in range(16))
self.secret_key = ''.join(random.choice(string.hexdigits) for i in range(32))
self.access_key = os.environ.get(self.ENV_ACCESS_KEY, ''.join(random.choice(string.hexdigits) for i in range(16)))
self.secret_key = os.environ.get(self.ENV_SECRET_KEY, ''.join(random.choice(string.hexdigits) for i in range(32)))
self.log_filename = (self.tempdir / 'minio').with_suffix(".log")
self.old_env = dict()
def __repr__(self):
return f"[minio] {self.address}:{self.port}/{self.bucket_name}@{self.config_file}"
@@ -155,8 +156,11 @@ class MinioServer:
with open(path, 'w', encoding='ascii') as config_file:
endpoint = {'name': address,
'port': port,
'aws_access_key_id': acc_key,
'aws_secret_access_key': secret_key,
# don't put credentials here. We're exporing env vars, which should
# be picked up properly by scylla.
# https://github.com/scylladb/scylla-pkg/issues/3845
#'aws_access_key_id': acc_key,
#'aws_secret_access_key': secret_key,
'aws_region': region,
}
yaml.dump({'endpoints': [endpoint]}, config_file)
@@ -186,6 +190,7 @@ class MinioServer:
return cmd
def _set_environ(self):
self.old_env = dict(os.environ)
os.environ[self.ENV_CONFFILE] = f'{self.config_file}'
os.environ[self.ENV_ADDRESS] = f'{self.address}'
os.environ[self.ENV_PORT] = f'{self.port}'
@@ -203,7 +208,10 @@ class MinioServer:
def _unset_environ(self):
for env in self._get_environs():
del os.environ[env]
if self.old_env[env] is not None:
os.environ[env] = self.old_env[env]
else:
del os.environ[env]
def print_environ(self):
msgs = []

View File

@@ -504,7 +504,8 @@ class ScyllaServer:
"""Start an installed server. May be used for restarts."""
env = os.environ.copy()
env.clear() # pass empty env to make user user's SCYLLA_HOME has no impact
# remove from env to make sure user's SCYLLA_HOME has no impact
env.pop('SCYLLA_HOME', None)
env.update(self.append_env)
env['UBSAN_OPTIONS'] = f'halt_on_error=1:abort_on_error=1:suppressions={os.getcwd()}/ubsan-suppressions.supp'
env['ASAN_OPTIONS'] = f'disable_coredump=0:abort_on_error=1:detect_stack_use_after_return=1'