From 371c90db0c5ceffc37ae99689dd50023d642326b Mon Sep 17 00:00:00 2001
From: Utz-Uwe Haus <uhaus@cray.com>
Date: Wed, 3 Nov 2021 14:33:00 +0100
Subject: [PATCH] Use MSTRO_NETWORK_CREDENTIALS in DRC init

---
 .gitignore                       |  1 +
 configure.ac                     |  1 +
 maestro/drc.c                    | 41 ++++++++++++++++++++--
 tests/Makefile.am                |  3 +-
 tests/check_multi_drc_init.sh.in | 58 ++++++++++++++++++++++++++++++++
 5 files changed, 101 insertions(+), 3 deletions(-)
 create mode 100644 tests/check_multi_drc_init.sh.in

diff --git a/.gitignore b/.gitignore
index 3598e611..1725a5cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,3 +111,4 @@ tests/check_cdo_selectors
 /tests/check_memlock
 MaestroConfig.cmake
 dst
+/tests/check_multi_drc_init.sh
diff --git a/configure.ac b/configure.ac
index 220dd6e8..49e7e8c4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -585,6 +585,7 @@ dnl AC_SUBST does not preserve executable bit on scripts, so do
 dnl substitution and chmod in 2 phases
 m4_define([TESTSCRIPTS],
   [tests/check_pm_declare.sh \
+   tests/check_multi_drc_init.sh \
    tests/check_pm_declare_group.sh \
    tests/check_pm_interlock.sh \
    tests/check_pm_collision.sh \
diff --git a/maestro/drc.c b/maestro/drc.c
index b7ee5c02..9665c970 100644
--- a/maestro/drc.c
+++ b/maestro/drc.c
@@ -149,6 +149,25 @@ mstro_drc_init_internal(mstro_drc_info result,
   return;
 }
 
+
+/* parse network credential and return its oob representation without
+ * the prefix string to the caller if successful */
+static mstro_status
+mstro__parse_network_credential(const char *netcred,
+                                /* fixme: update to a more general type */
+                                const char * *result)
+{
+  assert(netcred!=NULL);
+  if(strncasecmp(netcred,"drc:",4)!=0) {
+    /* FIXME: this needs expansion if we were to support other kinds */
+    ERR("Unsupported or invalid network credential: |%s|\n", netcred);
+    return MSTRO_INVARG;
+  }
+  *result = netcred + 4; /* the part after "drc:" */
+  return MSTRO_OK;
+}
+
+
 /** obtain DRC credentials */
 mstro_status
 mstro_drc_init(mstro_drc_info *result_p)
@@ -156,11 +175,28 @@ mstro_drc_init(mstro_drc_info *result_p)
   mstro_status stat = MSTRO_UNIMPL;
   if(result_p==NULL)
     return MSTRO_INVOUT;
-  
+
+  /* check for ENV override (reuse of existing DRC creds) */
+  char *external_token=getenv(MSTRO_ENV_NETWORK_CREDENTIALS);
+  if(external_token) {
+    const char * oob_string=NULL;
+    stat = mstro__parse_network_credential(external_token, &oob_string);
+    if(stat != MSTRO_OK) {
+      WARN("Ignoring unparsable network credential\n");
+      goto full_init;
+    } else {
+      DEBUG("Attempting init with externally provided network credential\n");
+      stat = mstro_drc_init_from_oob_string(result_p, oob_string);
+      goto BAILOUT;
+    }
+  }
+full_init:
   *result_p = malloc(sizeof(struct mstro_drc_info_));
   if(*result_p) {
     int ret;
     drc_info_handle_t info;
+
+
     char *do_nonflex = getenv(MSTRO_ENV_DRC_NON_FLEX);
     if(do_nonflex!=NULL && atoi(do_nonflex)!=0
        && do_nonflex[0]!='f' && do_nonflex[0]!='F' // fAlSe
@@ -169,7 +205,8 @@ mstro_drc_init(mstro_drc_info *result_p)
       // if user requests it: use non-flex credentials
       ret = drc_acquire(&(*result_p)->drc_id, 0);
     } else {
-      // default: flex credentials, to allow multiple jobs on the same node ("DRC node insecure mode")
+      // default: flex credentials, to allow multiple jobs on the same
+      // node ("DRC node insecure mode")
       ret = drc_acquire(&(*result_p)->drc_id,  DRC_FLAGS_FLEX_CREDENTIAL);
     }
       
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 42b1b3b7..bda6463d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -60,7 +60,7 @@ TESTS = check_version check_init check_uuid \
 	check_symtab \
 	check_events \
 	check_protobuf_c \
- 	check_transport_gfs \
+	check_transport_gfs \
 	check_layout \
         check_declare \
 	check_pool_local \
@@ -73,6 +73,7 @@ TESTS = check_version check_init check_uuid \
 	check_subscribe_local \
 	run_demo.sh \
         check_pool_manager \
+	check_multi_drc_init.sh \
 	check_pm_collision.sh \
 	check_pm_reentrant_client.sh \
 	check_pm_declare.sh \
diff --git a/tests/check_multi_drc_init.sh.in b/tests/check_multi_drc_init.sh.in
new file mode 100644
index 00000000..9516f59d
--- /dev/null
+++ b/tests/check_multi_drc_init.sh.in
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+#
+# Run pool manager twice and re-use the network credential from the first round for the second startup
+#
+
+# Copyright (C) 2021 Hewlett-Packard (Schweiz) GmbH
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+#    contributors may be used to endorse or promote products derived from
+#    this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# aggressive error tracing
+set -euo pipefail
+
+# set a workflow name
+MSTRO_WORKFLOW_NAME="check_multi_drc_init_wf_$$"
+export MSTRO_WORKFLOW_NAME
+
+# ensure error and warnings get colors
+MSTRO_LOG_COLOR_ERRORS=1
+export MSTRO_LOG_COLOR_ERRORS
+
+
+PM_CMD="@top_builddir@/tests/check_pool_manager"
+
+CREDMSG="$( ${PM_CMD} |grep "Got PM Net Cred:")" 
+
+CRED="$(echo ${CREDMSG} |cut -f2 -d\|)"
+
+if test x"$CRED" = x; then
+	exit 99
+fi
+
+env MSTRO_NETWORK_CREDENTIALS="${CRED}" ${PM_CMD} || exit 99
+
-- 
GitLab