Skip to content

Commit

Permalink
[#164,#189,#273] Run all storage tiering ops as admin
Browse files Browse the repository at this point in the history
This commit makes a couple of changes:

1. Added proxy_connection::make_rodsadmin_connection.
This function simply establishes a client connection as the
local service account rodsadmin. Importantly, it also sets
the authFlag in the created RcComm in order to appropriately
indicate the privilege level of the client user.

2. All instances of establishing a connection with the local
server to perform actions have been replaced with connections
as the local service account rodsadmin. This allows storage tiering
to do its job properly without needing to worry about user
permissions. Note: Violating queries still select the USER_NAME
and USER_ZONE, but they are no longer used.
  • Loading branch information
alanking committed Jan 15, 2025
1 parent 43ade4d commit 08e3019
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 75 deletions.
57 changes: 43 additions & 14 deletions include/irods/private/storage_tiering/proxy_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,59 @@ namespace irods {
rErrMsg_t err_msg;
rcComm_t* conn;

auto make(const std::string clientUser = "", const std::string clientZone = "") -> rcComm_t*
// Makes a proxy connection where the client is specified by the username in the parameters, and the proxy user
// is the service account rodsadmin for the local server.
auto make(const std::string& clientUser, const std::string& clientZone) -> rcComm_t*
{
rodsEnv env{};
_getRodsEnv(env);

conn = _rcConnect(
env.rodsHost,
env.rodsPort,
env.rodsUserName,
env.rodsZone,
!clientUser.empty() ?
clientUser.c_str() :
env.rodsUserName,
!clientZone.empty() ?
clientZone.c_str() :
env.rodsZone,
&err_msg,
0, 0);
// TODO(#296): Handle any errors which occur in _rcConnect or clientLogin.
conn = _rcConnect(env.rodsHost,
env.rodsPort,
env.rodsUserName,
env.rodsZone,
clientUser.c_str(),
clientZone.c_str(),
&err_msg,
0,
0);

clientLogin(conn);

return conn;
} // make

// Makes a proxy connection where both the proxy and client users are the service account rodsadmin for the
// local server.
auto make_rodsadmin_connection() -> RcComm*
{
rodsEnv env{};
_getRodsEnv(env);

// TODO(#296): Handle any errors which occur in _rcConnect or clientLogin.
conn = _rcConnect(env.rodsHost,
env.rodsPort,
env.rodsUserName,
env.rodsZone,
env.rodsUserName,
env.rodsZone,
&err_msg,
0,
0);

clientLogin(conn);

// Set the authFlag because auth plugin does not set it and the storage tiering plugin needs to know whether
// the client connection is privileged. This proxy connection uses the local client environment which should
// be the iRODS service account, a rodsadmin. If the local client environment is not a rodsadmin, the plugin
// will not function properly because it uses the ADMIN_KW and the server does not allow non-rodsadmins to
// use the ADMIN_KW.
conn->clientUser.authInfo.authFlag = LOCAL_PRIV_USER_AUTH;

return conn;
} // make_rodsadmin_connection

~proxy_connection() { rcDisconnect(conn); }
}; // proxy_connection

Expand Down
64 changes: 28 additions & 36 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <irods/apiNumber.h>
#include "irods/private/storage_tiering/data_verification_utilities.hpp"
#include <irods/irods_server_api_call.hpp>
#include "irods/private/storage_tiering/exec_as_user.hpp"

#include <irods/filesystem.hpp>
#include <irods/irods_at_scope_exit.hpp>
Expand Down Expand Up @@ -128,7 +127,7 @@ namespace {
addKeyVal(&data_obj_inp.condInput, DEST_RESC_NAME_KW, _destination_resource.c_str());

if(_comm->clientUser.authInfo.authFlag >= LOCAL_PRIV_USER_AUTH) {
addKeyVal(&data_obj_inp.condInput, ADMIN_KW, "true" );
addKeyVal(&data_obj_inp.condInput, ADMIN_KW, "");
}

transferStat_t* trans_stat{};
Expand Down Expand Up @@ -167,10 +166,7 @@ namespace {
COPIES_KW,
"1");
if(_comm->clientUser.authInfo.authFlag >= LOCAL_PRIV_USER_AUTH) {
addKeyVal(
&obj_inp.condInput,
ADMIN_KW,
"true" );
addKeyVal(&obj_inp.condInput, ADMIN_KW, "");
}

const auto trim_err = rcDataObjTrim(_comm, &obj_inp);
Expand Down Expand Up @@ -453,7 +449,7 @@ namespace {
parser.first_resc(source_resource);

auto proxy_conn = irods::proxy_connection();
rcComm_t* comm = proxy_conn.make(_rei->rsComm->clientUser.userName, _rei->rsComm->clientUser.rodsZone);
rcComm_t* comm = proxy_conn.make_rodsadmin_connection();

irods::storage_tiering st{comm, _rei, plugin_instance_name};

Expand Down Expand Up @@ -502,7 +498,7 @@ namespace {
auto [object_path, resource_name] = opened_objects[l1_idx];

auto proxy_conn = irods::proxy_connection();
rcComm_t* comm = proxy_conn.make(_rei->rsComm->clientUser.userName, _rei->rsComm->clientUser.rodsZone);
rcComm_t* comm = proxy_conn.make_rodsadmin_connection();

irods::storage_tiering st{comm, _rei, plugin_instance_name};
st.migrate_object_to_minimum_restage_tier(
Expand Down Expand Up @@ -689,7 +685,7 @@ irods::error exec_rule_text(
delay_obj["storage-tier-groups"] = rule_obj["storage-tier-groups"];

auto proxy_conn = irods::proxy_connection();
rcComm_t* comm = proxy_conn.make();
rcComm_t* comm = proxy_conn.make_rodsadmin_connection();

irods::storage_tiering st{comm, rei, plugin_instance_name};
st.schedule_storage_tiering_policy(
Expand Down Expand Up @@ -749,7 +745,7 @@ irods::error exec_rule_expression(
irods::storage_tiering::policy::storage_tiering == rule_obj.at("rule-engine-operation")) {
try {
auto proxy_conn = irods::proxy_connection();
rcComm_t* comm = proxy_conn.make();
rcComm_t* comm = proxy_conn.make_rodsadmin_connection();

irods::storage_tiering st{comm, rei, plugin_instance_name};
for(const auto& group : rule_obj["storage-tier-groups"]) {
Expand All @@ -773,34 +769,30 @@ irods::error exec_rule_expression(
auto& pin = plugin_instance_name;

auto proxy_conn = irods::proxy_connection();
rcComm_t* comm = proxy_conn.make( rule_obj["user-name"], rule_obj["user-zone"]);

auto status = irods::exec_as_user(comm, user_name, user_zone, [& pin, & rule_obj](auto& comm) -> int{
return apply_data_movement_policy(
comm,
plugin_instance_name,
rule_obj["object-path"],
rule_obj["user-name"],
rule_obj["user-zone"],
rule_obj["source-replica-number"],
rule_obj["source-resource"],
rule_obj["destination-resource"],
rule_obj["preserve-replicas"],
rule_obj["verification-type"]);
});
rcComm_t* comm = proxy_conn.make_rodsadmin_connection();

// TODO(#297): Use get or get_ref for these parameters.
auto status = apply_data_movement_policy(comm,
plugin_instance_name,
rule_obj["object-path"],
rule_obj["user-name"],
rule_obj["user-zone"],
rule_obj["source-replica-number"],
rule_obj["source-resource"],
rule_obj["destination-resource"],
rule_obj["preserve-replicas"],
rule_obj["verification-type"]);

irods::storage_tiering st{comm, rei, plugin_instance_name};
status = irods::exec_as_user(comm, user_name, user_zone, [& st, & rule_obj](auto& comm) -> int{
return apply_tier_group_metadata_policy(
st,
rule_obj["group-name"],
rule_obj["object-path"],
rule_obj["user-name"],
rule_obj["user-zone"],
rule_obj["source-replica-number"],
rule_obj["source-resource"],
rule_obj["destination-resource"]);
});
// TODO(#297): Use get or get_ref for these parameters.
status = apply_tier_group_metadata_policy(st,
rule_obj["group-name"],
rule_obj["object-path"],
rule_obj["user-name"],
rule_obj["user-zone"],
rule_obj["source-replica-number"],
rule_obj["source-resource"],
rule_obj["destination-resource"]);
}
catch(const irods::exception& _e) {
printErrorStack(&rei->rsComm->rError);
Expand Down
43 changes: 18 additions & 25 deletions src/storage_tiering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#include "irods/private/storage_tiering/data_verification_utilities.hpp"

#include "irods/private/storage_tiering/exec_as_user.hpp"

#include <boost/any.hpp>
#include <boost/regex.hpp>
Expand Down Expand Up @@ -626,7 +625,7 @@ namespace irods {
object_is_processed[object_path] = 1;

auto proxy_conn = irods::proxy_connection();
rcComm_t* comm = proxy_conn.make(_results[2], _results[3]);
rcComm_t* comm = proxy_conn.make_rodsadmin_connection();

if(preserve_replicas) {
if(skip_object_in_lower_tier(
Expand Down Expand Up @@ -979,14 +978,12 @@ namespace irods {
const_cast<char*>(access_time.c_str()),
const_cast<char*>(config_.migration_scheduled_flag.c_str())};

auto status = exec_as_user(_comm, _user_name, _user_zone, [&set_op](auto comm) -> int {
return rcModAVUMetadata(comm, &set_op);
});
if(status < 0) {
THROW(
status,
boost::format("failed to set migration scheduled flag for [%s]")
% _object_path);
if (_comm->clientUser.authInfo.authFlag >= LOCAL_PRIV_USER_AUTH) {
addKeyVal(&set_op.condInput, ADMIN_KW, "");
}

if (const auto ec = rcModAVUMetadata(_comm, &set_op); ec < 0) {
THROW(ec, fmt::format("failed to set migration scheduled flag for [{}]", _object_path));
}
} // set_migration_metadata_flag_for_object

Expand All @@ -1007,16 +1004,13 @@ namespace irods {
const_cast<char*>(access_time.c_str()),
nullptr};

const auto status = exec_as_user(_comm, _user_name, _user_zone, [&set_op](auto comm) -> int {
return rcModAVUMetadata(comm, &set_op);
});
if(status < 0) {
THROW(
status,
boost::format("failed to unset migration scheduled flag for [%s]")
% _object_path);
if (_comm->clientUser.authInfo.authFlag >= LOCAL_PRIV_USER_AUTH) {
addKeyVal(&set_op.condInput, ADMIN_KW, "");
}

if (const auto ec = rcModAVUMetadata(_comm, &set_op); ec < 0) {
THROW(ec, fmt::format("failed to unset migration scheduled flag for [{}]", _object_path));
}
} // unset_migration_metadata_flag_for_object

bool storage_tiering::object_has_migration_metadata_flag(
Expand All @@ -1036,13 +1030,8 @@ namespace irods {
% data_name
% coll_name) };

const auto status = exec_as_user(_comm, _user_name, _user_zone, [& query_str](auto& _comm) -> int {
query<rcComm_t> qobj{_comm, query_str, 1};
return qobj.size();
});

return status > 0;

query<rcComm_t> qobj{_comm, query_str, 1};
return qobj.size() > 0;
} // object_has_migration_metadata_flag

void storage_tiering::apply_tier_group_metadata_to_object(
Expand Down Expand Up @@ -1073,6 +1062,10 @@ namespace irods {
const_cast<char*>(_group_name.c_str()),
const_cast<char*>(destination_replica_number.c_str())};

if (comm_->clientUser.authInfo.authFlag >= LOCAL_PRIV_USER_AUTH) {
addKeyVal(&set_op.condInput, ADMIN_KW, "");
}

auto status = rcModAVUMetadata(comm_, &set_op);
if(status < 0) {
THROW(
Expand Down

0 comments on commit 08e3019

Please sign in to comment.