From cd04cf9ac243f3ce02f9b473cfe422a30561717d Mon Sep 17 00:00:00 2001 From: cmoussa1 Date: Tue, 6 Aug 2024 16:07:49 -0700 Subject: [PATCH 1/2] view-user: add --list-banks option Problem: There is no concise way to view the banks that a user belongs to. Add a --list-banks optional argument to view-user, which will just print the banks that a user belongs to in the flux-accounting database. --- .../python/fluxacct/accounting/formatter.py | 18 ++++++++++++++++++ .../fluxacct/accounting/user_subcommands.py | 4 +++- src/cmd/flux-account-service.py | 1 + src/cmd/flux-account.py | 7 +++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/bindings/python/fluxacct/accounting/formatter.py b/src/bindings/python/fluxacct/accounting/formatter.py index a8763d6d..9fcecfca 100644 --- a/src/bindings/python/fluxacct/accounting/formatter.py +++ b/src/bindings/python/fluxacct/accounting/formatter.py @@ -306,3 +306,21 @@ def __init__(self, cursor, username): super().__init__( cursor, error_msg=f"user {self.username} not found in association_table" ) + + def list_banks(self): + """ + Return all of the banks that the user belongs to with each bank + on its own line. + + Args: + username: the name of the user. + """ + self.cursor.execute( + "SELECT bank FROM association_table WHERE username=?", (self.username,) + ) + result = self.cursor.fetchall() + banks = "" + for bank in result: + banks += f"{str(bank[0])}\n" + + return banks diff --git a/src/bindings/python/fluxacct/accounting/user_subcommands.py b/src/bindings/python/fluxacct/accounting/user_subcommands.py index 7835f1e4..a6ee195f 100755 --- a/src/bindings/python/fluxacct/accounting/user_subcommands.py +++ b/src/bindings/python/fluxacct/accounting/user_subcommands.py @@ -233,7 +233,7 @@ def clear_projects(conn, username, bank=None): # Subcommand Functions # # # ############################################################### -def view_user(conn, user, parsable=False, cols=None): +def view_user(conn, user, parsable=False, cols=None, list_banks=False): # use all column names if none are passed in cols = cols or fluxacct.accounting.ASSOCIATION_TABLE @@ -250,6 +250,8 @@ def view_user(conn, user, parsable=False, cols=None): # initialize AssociationFormatter object formatter = fmt.AssociationFormatter(cur, user) + if list_banks: + return formatter.list_banks() if parsable: return formatter.as_table() return formatter.as_json() diff --git a/src/cmd/flux-account-service.py b/src/cmd/flux-account-service.py index 9db7056a..0c9e6b41 100755 --- a/src/cmd/flux-account-service.py +++ b/src/cmd/flux-account-service.py @@ -150,6 +150,7 @@ def view_user(self, handle, watcher, msg, arg): msg.payload["username"], msg.payload["parsable"], msg.payload["fields"].split(",") if msg.payload.get("fields") else None, + msg.payload["list_banks"], ) payload = {"view_user": val} diff --git a/src/cmd/flux-account.py b/src/cmd/flux-account.py index 9478218b..10d8fb2d 100755 --- a/src/cmd/flux-account.py +++ b/src/cmd/flux-account.py @@ -57,6 +57,13 @@ def add_view_user_arg(subparsers): "MAX_CORES,QUEUES,PROJECTS,DEFAULT_PROJECT" ), ) + subparser_view_user.add_argument( + "--list-banks", + action="store_const", + const=True, + help="list all of the banks a user belongs to", + metavar="LIST_BANKS", + ) def add_add_user_arg(subparsers): From d4ed37555575f502a27485f571e3e424c3e6e4eb Mon Sep 17 00:00:00 2001 From: cmoussa1 Date: Tue, 6 Aug 2024 16:10:11 -0700 Subject: [PATCH 2/2] t: add tests for calling view-user --list-banks Problem: There exists no tests for calling view-user with the --list-banks option. Add some tests. --- t/Makefile.am | 1 + t/t1045-issue478.t | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100755 t/t1045-issue478.t diff --git a/t/Makefile.am b/t/Makefile.am index 97edba86..0366d1a0 100644 --- a/t/Makefile.am +++ b/t/Makefile.am @@ -44,6 +44,7 @@ TESTSCRIPTS = \ t1042-issue508.t \ t1043-view-jobs-by-bank.t \ t1044-mf-priority-resource-limits.t \ + t1045-issue478.t \ t5000-valgrind.t \ python/t1000-example.py \ python/t1001_db.py \ diff --git a/t/t1045-issue478.t b/t/t1045-issue478.t new file mode 100755 index 00000000..b843ccdf --- /dev/null +++ b/t/t1045-issue478.t @@ -0,0 +1,49 @@ +#!/bin/bash + +test_description='test calling view-user with the --list-banks optional argument' + +. `dirname $0`/sharness.sh + +mkdir -p conf.d + +ACCOUNTING_DB=$(pwd)/FluxAccountingTest.db + +export TEST_UNDER_FLUX_SCHED_SIMPLE_MODE="limited=1" +test_under_flux 1 job -o,--config-path=$(pwd)/conf.d + +flux setattr log-stderr-level 1 + +test_expect_success 'create flux-accounting DB, start flux-accounting service' ' + flux account -p ${ACCOUNTING_DB} create-db && + flux account-service -p ${ACCOUNTING_DB} -t +' + +test_expect_success 'add some banks' ' + flux account add-bank root 1 && + flux account add-bank --parent-bank=root bankA 1 && + flux account add-bank --parent-bank=root bankB 1 && + flux account add-bank --parent-bank=root bankC 1 +' + +test_expect_success 'add a user' ' + flux account add-user --username=testuser --bank=bankA && + flux account add-user --username=testuser --bank=bankB && + flux account add-user --username=testuser --bank=bankC +' + +test_expect_success 'call view-user --list-banks' ' + flux account view-user testuser --list-banks > banks.out && + grep "bankA" banks.out && + grep "bankB" banks.out && + grep "bankC" banks.out +' + +test_expect_success 'shut down flux-accounting service' ' + flux python -c "import flux; flux.Flux().rpc(\"accounting.shutdown_service\").get()" +' + +test_expect_success 'remove flux-accounting DB' ' + rm ${ACCOUNTING_DB} +' + +test_done