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

Allow node to enroll to cluster on startup #77718

Merged
merged 68 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
aeec13d
Allow node to enroll to cluster on startup
jkakavas Sep 14, 2021
4c17742
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Sep 14, 2021
f9a14b8
Add packaging tests(first of many commits)
jkakavas Sep 15, 2021
226e965
supress forbidden warning for necessary use
jkakavas Sep 15, 2021
a15b6bc
close if not null
jkakavas Sep 15, 2021
99afe27
proper settings
jkakavas Sep 15, 2021
ca0836c
Shift only when there are more args
jkakavas Sep 15, 2021
068e45d
temp
jkakavas Sep 15, 2021
be92ca1
correct mock esNode ssl config to return the entire chain
jkakavas Sep 15, 2021
ba11466
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Sep 15, 2021
5c0c1f0
fixes
jkakavas Sep 15, 2021
062cb85
more fixes
jkakavas Sep 15, 2021
2f3c337
final fixes
jkakavas Sep 16, 2021
74ef40b
(mostly) fix batch startup script
jkakavas Sep 16, 2021
140d2c4
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Sep 16, 2021
fb8686c
update batch file
jkakavas Sep 16, 2021
b480b4e
feedback
jkakavas Sep 19, 2021
7941370
adjust test
jkakavas Sep 20, 2021
8ca65fa
Call CLI tool from batch script
jkakavas Sep 20, 2021
2d8b395
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Sep 21, 2021
f631474
change how we populate SANs
jkakavas Sep 21, 2021
1efbc06
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Sep 21, 2021
0c1fee9
non null hostnames
jkakavas Sep 22, 2021
345329e
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 18, 2021
36fc590
Scope down the PR to just allow users to pass the enrollment-token on…
jkakavas Oct 19, 2021
fd14936
cleanup qa
jkakavas Oct 19, 2021
6dbb3fa
remove redundant testing
jkakavas Oct 19, 2021
5dbfba3
Revert "remove redundant testing"
jkakavas Oct 19, 2021
2daabc5
remove redundant test - correctly this time
jkakavas Oct 19, 2021
caa5880
reintroduce a simpler version of packaging tests
jkakavas Oct 19, 2021
d6018d3
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 19, 2021
14b679a
windows tests
jkakavas Oct 19, 2021
881d001
use EnrollmentToken class in tests
jkakavas Oct 19, 2021
1758026
spotless
jkakavas Oct 19, 2021
026341d
spotless
jkakavas Oct 19, 2021
c6f123e
fix token param checking
jkakavas Oct 20, 2021
bfbfee0
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 20, 2021
4222f7c
Fix test
jkakavas Oct 20, 2021
a3cae59
Adjust startup scripts
jkakavas Oct 20, 2021
7331c71
cleanup
jkakavas Oct 20, 2021
2d04043
mute test on windows
jkakavas Oct 20, 2021
aebba35
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 20, 2021
3643d72
mute on windows
jkakavas Oct 20, 2021
4198cc8
change test while figuring the cause
jkakavas Oct 20, 2021
573add3
Fix argument handling
jkakavas Oct 21, 2021
38623c6
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 21, 2021
0ced955
remove code that can wait until the follow-up PR for the CLI tool
jkakavas Oct 21, 2021
9efae09
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 23, 2021
48b7569
Use enrollment token on startup in tests
jkakavas Oct 23, 2021
d0e9e6c
add failure information output in verbose mode
jkakavas Oct 24, 2021
a3c9a21
a space is not a -
jkakavas Oct 24, 2021
18ed565
account for the fact that the second node binds to 9201 in Enrollment…
jkakavas Oct 24, 2021
f09cba0
test
jkakavas Oct 24, 2021
347e4b9
Ugly hacks are ugly
jkakavas Oct 24, 2021
d8729ce
tightly scope try blocks
jkakavas Oct 25, 2021
7693119
address feedback
jkakavas Oct 25, 2021
1138134
dissallow multiple --enrollment-token paramaters
jkakavas Oct 26, 2021
ee03466
Generate a CA and sign transport certificates with this
jkakavas Oct 26, 2021
0ca60d1
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 26, 2021
e00aa95
Transport CA cert needs to be transmitted to all nodes to be used in …
jkakavas Oct 26, 2021
491dbf5
disallow multiple --enrollment-token params on windows too
jkakavas Oct 26, 2021
d7ba414
print to stderr on windows
jkakavas Oct 26, 2021
5859676
windows exit code handling is totally bonkers
jkakavas Oct 26, 2021
10fec73
stderr
jkakavas Oct 26, 2021
631d22c
fix test
jkakavas Oct 26, 2021
b635b96
fix test
jkakavas Oct 26, 2021
eaeafe8
Merge remote-tracking branch 'origin/master' into enroll-as-a-param
jkakavas Oct 27, 2021
5b796df
merge woes
jkakavas Oct 27, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public void testEnrollNode() throws Exception {
assertThat(nodeEnrollmentResponse, notNullValue());
assertThat(nodeEnrollmentResponse.getHttpCaKey(), endsWith("K2S3vidA="));
assertThat(nodeEnrollmentResponse.getHttpCaCert(), endsWith("LfkRjirc="));
assertThat(nodeEnrollmentResponse.getTransportCaCert(), endsWith("3J9+kpgIbE"));
assertThat(nodeEnrollmentResponse.getTransportKey(), endsWith("1I+r8vOQ=="));
assertThat(nodeEnrollmentResponse.getTransportCert(), endsWith("OpTdtgJo="));
List<String> nodesAddresses = nodeEnrollmentResponse.getNodesAddresses();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ public void testNodeEnrollment() throws Exception {
// tag::node-enrollment-response
String httpCaKey = response.getHttpCaKey(); // <1>
String httpCaCert = response.getHttpCaCert(); // <2>
String transportKey = response.getTransportKey(); // <3>
String transportCert = response.getTransportCert(); // <4>
List<String> nodesAddresses = response.getNodesAddresses(); // <5>
String transportCaCert = response.getTransportCaCert(); // <3>
String transportKey = response.getTransportKey(); // <4>
String transportCert = response.getTransportCert(); // <5>
List<String> nodesAddresses = response.getNodesAddresses(); // <6>
// end::node-enrollment-response
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ public class NodeEnrollmentResponse {

private final String httpCaKey;
private final String httpCaCert;
private final String transportCaCert;
private final String transportKey;
private final String transportCert;
private final List<String> nodesAddresses;

public NodeEnrollmentResponse(String httpCaKey, String httpCaCert, String transportKey, String transportCert,
public NodeEnrollmentResponse(String httpCaKey, String httpCaCert, String transportCaCert, String transportKey, String transportCert,
List<String> nodesAddresses){
this.httpCaKey = httpCaKey;
this.httpCaCert = httpCaCert;
this.transportCaCert = transportCaCert;
this.transportKey = transportKey;
this.transportCert = transportCert;
this.nodesAddresses = Collections.unmodifiableList(nodesAddresses);
Expand All @@ -46,6 +48,10 @@ public String getTransportKey() {
return transportKey;
}

public String getTransportCaCert() {
return transportCaCert;
}

public String getTransportCert() {
return transportCert;
}
Expand All @@ -56,6 +62,7 @@ public List<String> getNodesAddresses() {

private static final ParseField HTTP_CA_KEY = new ParseField("http_ca_key");
private static final ParseField HTTP_CA_CERT = new ParseField("http_ca_cert");
private static final ParseField TRANSPORT_CA_CERT = new ParseField("transport_ca_cert");
private static final ParseField TRANSPORT_KEY = new ParseField("transport_key");
private static final ParseField TRANSPORT_CERT = new ParseField("transport_cert");
private static final ParseField NODES_ADDRESSES = new ParseField("nodes_addresses");
Expand All @@ -66,15 +73,17 @@ public List<String> getNodesAddresses() {
new ConstructingObjectParser<>(NodeEnrollmentResponse.class.getName(), true, a -> {
final String httpCaKey = (String) a[0];
final String httpCaCert = (String) a[1];
final String transportKey = (String) a[2];
final String transportCert = (String) a[3];
final List<String> nodesAddresses = (List<String>) a[4];
return new NodeEnrollmentResponse(httpCaKey, httpCaCert, transportKey, transportCert, nodesAddresses);
final String transportCaCert = (String) a[2];
final String transportKey = (String) a[3];
final String transportCert = (String) a[4];
final List<String> nodesAddresses = (List<String>) a[5];
return new NodeEnrollmentResponse(httpCaKey, httpCaCert, transportCaCert, transportKey, transportCert, nodesAddresses);
});

static {
PARSER.declareString(ConstructingObjectParser.constructorArg(), HTTP_CA_KEY);
PARSER.declareString(ConstructingObjectParser.constructorArg(), HTTP_CA_CERT);
PARSER.declareString(ConstructingObjectParser.constructorArg(), TRANSPORT_CA_CERT);
PARSER.declareString(ConstructingObjectParser.constructorArg(), TRANSPORT_KEY);
PARSER.declareString(ConstructingObjectParser.constructorArg(), TRANSPORT_CERT);
PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), NODES_ADDRESSES);
Expand All @@ -88,12 +97,15 @@ public static NodeEnrollmentResponse fromXContent(XContentParser parser) throws
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NodeEnrollmentResponse that = (NodeEnrollmentResponse) o;
return httpCaKey.equals(that.httpCaKey) && httpCaCert.equals(that.httpCaCert) && transportKey.equals(that.transportKey)
return httpCaKey.equals(that.httpCaKey)
&& httpCaCert.equals(that.httpCaCert)
&& transportCaCert.equals(that.transportCaCert)
&& transportKey.equals(that.transportKey)
&& transportCert.equals(that.transportCert)
&& nodesAddresses.equals(that.nodesAddresses);
}

@Override public int hashCode() {
return Objects.hash(httpCaKey, httpCaCert, transportKey, transportCert, nodesAddresses);
return Objects.hash(httpCaKey, httpCaCert, transportCaCert, transportKey, transportCert, nodesAddresses);
}
}
12 changes: 6 additions & 6 deletions distribution/packages/src/common/scripts/postinst
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ if [ "x$IS_UPGRADE" != "xtrue" ]; then
# Don't exit immediately on error, we want to hopefully print some helpful banners
set +e
# Attempt to auto-configure security, this seems to be an installation
if ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.ConfigInitialNode \
if ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
/usr/share/elasticsearch/bin/elasticsearch-cli <<< ""; then
# Above command runs as root and TLS keystores are created group-owned by root. It's simple to correct the ownership here
for dir in "${ES_PATH_CONF}"/tls_auto_config_initial_node_*
for dir in "${ES_PATH_CONF}"/tls_auto_config_*
do
chown root:elasticsearch "${dir}"/http_keystore_local_node.p12
chown root:elasticsearch "${dir}"/http_ca.crt
Expand All @@ -83,13 +83,13 @@ if [ "x$IS_UPGRADE" != "xtrue" ]; then
echo "You can complete the following actions at any time:"
echo
echo "Reset the password of the elastic built-in superuser with "
echo "'/usr/share/bin/elasticsearch-reset-password -u elastic'."
echo "'/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'."
echo
echo "Generate an enrollment token for Kibana instances with "
echo " 'bin/elasticsearch-create-enrollment-token -s kibana'."
echo " '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'."
echo
echo "Generate an enrollment token for Elasticsearch nodes with "
echo "'bin/elasticsearch-create-enrollment-token -s node'."
echo "'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'."
echo
echo "-------------------------------------------------------------------------------------------------"
fi
Expand All @@ -108,7 +108,7 @@ if [ "x$IS_UPGRADE" != "xtrue" ]; then
echo "However, authentication and authorization are still enabled."
echo
echo "You can reset the password of the elastic built-in superuser with "
echo "'/usr/share/bin/elasticsearch-reset-password -u elastic' at any time."
echo "'/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic' at any time."
echo "-------------------------------------------------------------------------------------------------"
fi
fi
Expand Down
2 changes: 1 addition & 1 deletion distribution/packages/src/common/scripts/postrm
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ if [ "$REMOVE_DIRS" = "true" ]; then

# delete the security auto config directory if we are purging
if [ "$REMOVE_SECURITY_AUTO_CONFIG_DIRECTORY" = "true" ]; then
for dir in "${ES_PATH_CONF}"/tls_auto_config_initial_node_*
for dir in "${ES_PATH_CONF}"/tls_auto_config_*
do
echo -n "Deleting security auto-configuration directory..."
rm -rf "${dir}"
Expand Down
55 changes: 40 additions & 15 deletions distribution/src/bin/elasticsearch
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,29 @@ source "`dirname "$0"`"/elasticsearch-env
CHECK_KEYSTORE=true
ATTEMPT_SECURITY_AUTO_CONFIG=true
DAEMONIZE=false
for option in "$@"; do
case "$option" in
-h|--help|-V|--version)
CHECK_KEYSTORE=false
ATTEMPT_SECURITY_AUTO_CONFIG=false
;;
-d|--daemonize)
DAEMONIZE=true
;;
esac
ENROLL_TO_CLUSTER=false
# Store original arg array as we will be shifting through it below
ARG_LIST=("$@")

while [ $# -gt 0 ]; do
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the way we are iterating over the args, so that we can capture the value of the enrollment token. We need this so that we can remove it from the args array that we end up passing to elasticserach process to start in the end, as elasticsearch will not allow for unrecognized options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about why you iterate through $@ here (effectively), rather than $ARG_LIST.
If you just iterated through ARG_LIST you could remove the enrollment token in a single pass rather than needing to iterate again later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using SHIFT in this iteration so that I can recognize the named arg that comes after --enrollment-token. If Iwas to iterate over ARG_LIST , I'd be removing args from it while iterating so I wouldn't be able to use it below.

Or, I am missing your point, let me know :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not important, but you could do something like this:

for i in "${!ARG_LIST[@]}"; do
  case "${ARG_LIST[i]}" in
    --enrollment-token)
      ENROLL_TO_CLUSTER=true
      ATTEMPT_SECURITY_AUTO_CONFIG=false
      unset 'ARG_LIST[i]'
      let i++
      ENROLLMENT_TOKEN="${ARG_LIST[i]}"
      unset 'ARG_LIST[i]'
      ;;
    -h|--help|-V|--version)
      CHECK_KEYSTORE=false
      ATTEMPT_SECURITY_AUTO_CONFIG=false
      ;;
    -d|--daemonize)
      DAEMONIZE=true
      ;;
  esac
done

if [[ $1 == "--enrollment-token" ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I would have stuck with a case rather than a series of if/elif

if [ $ENROLL_TO_CLUSTER = true ]; then
echo "Multiple --enrollment-token parameters are not allowed" 1>&2
exit 1
fi
ENROLL_TO_CLUSTER=true
ATTEMPT_SECURITY_AUTO_CONFIG=false
ENROLLMENT_TOKEN="$2"
jkakavas marked this conversation as resolved.
Show resolved Hide resolved
shift
elif [[ $1 == "-h" || $1 == "--help" || $1 == "-V" || $1 == "--version" ]]; then
CHECK_KEYSTORE=false
ATTEMPT_SECURITY_AUTO_CONFIG=false
elif [[ $1 == "-d" || $1 == "--daemonize" ]]; then
DAEMONIZE=true
fi
if [[ $# -gt 0 ]]; then
shift
fi
done

if [ -z "$ES_TMPDIR" ]; then
Expand All @@ -47,16 +60,21 @@ then
fi
fi

if [[ $ATTEMPT_SECURITY_AUTO_CONFIG = true ]]; then
if [[ $ENROLL_TO_CLUSTER = true ]]; then
ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
bin/elasticsearch-cli "${ARG_LIST[@]}" <<<"$KEYSTORE_PASSWORD"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have shifted through $@ so we need to use "${ARG_LIST[@]}" that contains a copy of the original args

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to check the return value here. Any ExitCode should make us stop because we cannot satisfy an explicit request of the user ( to enroll this node to an existing cluster) .

elif [[ $ATTEMPT_SECURITY_AUTO_CONFIG = true ]]; then
# It is possible that an auto-conf failure prevents the node from starting, but this is only the exceptional case (exit code 1).
# Most likely an auto-conf failure will leave the configuration untouched (exit codes 73, 78 and 80), optionally printing a message
# if the error is uncommon or unexpected, but it should otherwise let the node to start as usual.
# It is passed in all the command line options in order to read the node settings ones (-E), while the other parameters are ignored
# (a small caveat is that it also inspects the -v option in order to provide more information on how auto config went)
if ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.ConfigInitialNode \
if ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
bin/elasticsearch-cli "$@" <<<"$KEYSTORE_PASSWORD"; then
bin/elasticsearch-cli "${ARG_LIST[@]}" <<<"$KEYSTORE_PASSWORD"; then
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have shifted through $@ so we need to use "${ARG_LIST[@]}" that contains a copy of the original args ( along with --enrollment-token <token value> in this case )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I missing something or are these two scenarios identical? What's the difference between ENROLL_TO_CLUSTER being true and ATTEMPT_SECURITY_AUTO_CONFIG?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is slightly confusing. Both scenarios call the same class passing that arguments of the user, but :

  • (maybe obvious, but for the benefit of all readers) the ENROLL_TO_CLUSTER being true branch means that there are user provided args (--enrollment-token) that make AutoConfigureNode behave slightly differently than it would if it was the ATTEMPT_SECURITY_AUTO_CONFIG branch.
  • we do different error handling. In the case of ATTEMPT_SECURITY_AUTO_CONFIG , we are attempting auto-configuration on behalf of the user and there are certain cases where we want this to be a no-op and just start the node( i.e. already configured node, etc ), while in the ENROLL_TO_CLUSTER branch, the user explicitly asked us to perform an action for them so if we can't do it, we notify them and exit.

:
else
retval=$?
Expand All @@ -77,6 +95,13 @@ fi
# - fourth, ergonomic JVM options are applied
ES_JAVA_OPTS=`export ES_TMPDIR; "$JAVA" "$XSHARE" -cp "$ES_CLASSPATH" org.elasticsearch.tools.launchers.JvmOptionsParser "$ES_PATH_CONF" "$ES_HOME/plugins"`

# Remove enrollment related parameters before passing the arg list to Elasticsearch
for i in "${!ARG_LIST[@]}"; do
if [[ ${ARG_LIST[i]} = "--enrollment-token" || ${ARG_LIST[i]} = "$ENROLLMENT_TOKEN" ]]; then
unset 'ARG_LIST[i]'
fi
done

# manual parsing to find out, if process should be detached
if [[ $DAEMONIZE = false ]]; then
exec \
Expand All @@ -90,7 +115,7 @@ if [[ $DAEMONIZE = false ]]; then
-Des.bundled_jdk="$ES_BUNDLED_JDK" \
-cp "$ES_CLASSPATH" \
org.elasticsearch.bootstrap.Elasticsearch \
"$@" <<<"$KEYSTORE_PASSWORD"
"${ARG_LIST[@]}" <<<"$KEYSTORE_PASSWORD"
else
exec \
"$JAVA" \
Expand All @@ -103,7 +128,7 @@ else
-Des.bundled_jdk="$ES_BUNDLED_JDK" \
-cp "$ES_CLASSPATH" \
org.elasticsearch.bootstrap.Elasticsearch \
"$@" \
"${ARG_LIST[@]}" \
<<<"$KEYSTORE_PASSWORD" &
retval=$?
pid=$!
Expand Down
68 changes: 53 additions & 15 deletions distribution/src/bin/elasticsearch.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ setlocal enableextensions

SET params='%*'
SET checkpassword=Y
SET enrolltocluster=N
SET attemptautoconfig=Y

:loop
FOR /F "usebackq tokens=1* delims= " %%A IN (!params!) DO (
SET previous=!current!
SET current=%%A
SET params='%%B'
SET silent=N

IF "!current!" == "-s" (
SET silent=Y
)
Expand All @@ -38,14 +39,33 @@ FOR /F "usebackq tokens=1* delims= " %%A IN (!params!) DO (
SET attemptautoconfig=N
)

IF "!current!" == "--enrollment-token" (
IF "!enrolltocluster!" == "Y" (
ECHO "Multiple --enrollment-token parameters are not allowed" 1>&2
goto exitwithone
)
SET enrolltocluster=Y
SET attemptautoconfig=N
)

IF "!previous!" == "--enrollment-token" (
SET enrollmenttoken="!current!"
)

IF "!silent!" == "Y" (
SET nopauseonerror=Y
) ELSE (
IF "x!newparams!" NEQ "x" (
SET newparams=!newparams! !current!
) ELSE (
SET newparams=!current!
)
SET SHOULD_SKIP=false
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skip adding --enrollment-token and its value to the newparams so that we don't pass it to the elasticsearch process

IF "!previous!" == "--enrollment-token" SET SHOULD_SKIP=true
IF "!current!" == "--enrollment-token" SET SHOULD_SKIP=true
IF "!SHOULD_SKIP!" == "false" (
IF "x!newparams!" NEQ "x" (
SET newparams=!newparams! !current!
) ELSE (
SET newparams=!current!
)
)

)

IF "x!params!" NEQ "x" (
Expand Down Expand Up @@ -73,13 +93,21 @@ IF "%checkpassword%"=="Y" (
)
)

rem windows batch pipe will choke on special characters in strings
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^^=^^^^!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^&=^^^&!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^|=^^^|!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^<=^^^<!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^>=^^^>!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^\=^^^\!

IF "%attemptautoconfig%"=="Y" (
ECHO.!KEYSTORE_PASSWORD!| %JAVA% %ES_JAVA_OPTS% ^
-Des.path.home="%ES_HOME%" ^
-Des.path.conf="%ES_PATH_CONF%" ^
-Des.distribution.flavor="%ES_DISTRIBUTION_FLAVOR%" ^
-Des.distribution.type="%ES_DISTRIBUTION_TYPE%" ^
-cp "!ES_CLASSPATH!;!ES_HOME!/lib/tools/security-cli/*;!ES_HOME!/modules/x-pack-core/*;!ES_HOME!/modules/x-pack-security/*" "org.elasticsearch.xpack.security.cli.ConfigInitialNode" !newparams!
-cp "!ES_CLASSPATH!;!ES_HOME!/lib/tools/security-cli/*;!ES_HOME!/modules/x-pack-core/*;!ES_HOME!/modules/x-pack-security/*" "org.elasticsearch.xpack.security.cli.AutoConfigureNode" !newparams!
SET SHOULDEXIT=Y
IF !ERRORLEVEL! EQU 0 SET SHOULDEXIT=N
IF !ERRORLEVEL! EQU 73 SET SHOULDEXIT=N
Expand All @@ -90,6 +118,19 @@ IF "%attemptautoconfig%"=="Y" (
)
)

IF "!enrolltocluster!"=="Y" (
ECHO.!KEYSTORE_PASSWORD!| %JAVA% %ES_JAVA_OPTS% ^
-Des.path.home="%ES_HOME%" ^
-Des.path.conf="%ES_PATH_CONF%" ^
-Des.distribution.flavor="%ES_DISTRIBUTION_FLAVOR%" ^
-Des.distribution.type="%ES_DISTRIBUTION_TYPE%" ^
-cp "!ES_CLASSPATH!;!ES_HOME!/lib/tools/security-cli/*;!ES_HOME!/modules/x-pack-core/*;!ES_HOME!/modules/x-pack-security/*" "org.elasticsearch.xpack.security.cli.AutoConfigureNode" ^
!newparams! --enrollment-token %enrollmenttoken%
IF !ERRORLEVEL! NEQ 0 (
exit /b !ERRORLEVEL!
)
)

if not defined ES_TMPDIR (
for /f "tokens=* usebackq" %%a in (`CALL %JAVA% -cp "!ES_CLASSPATH!" "org.elasticsearch.tools.launchers.TempDirectory"`) do set ES_TMPDIR=%%a
)
Expand All @@ -111,14 +152,6 @@ if "%MAYBE_JVM_OPTIONS_PARSER_FAILED%" == "jvm_options_parser_failed" (
exit /b 1
)

rem windows batch pipe will choke on special characters in strings
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^^=^^^^!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^&=^^^&!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^|=^^^|!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^<=^^^<!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^>=^^^>!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^\=^^^\!

ECHO.!KEYSTORE_PASSWORD!| %JAVA% %ES_JAVA_OPTS% -Delasticsearch ^
-Des.path.home="%ES_HOME%" -Des.path.conf="%ES_PATH_CONF%" ^
-Des.distribution.flavor="%ES_DISTRIBUTION_FLAVOR%" ^
Expand All @@ -129,3 +162,8 @@ ECHO.!KEYSTORE_PASSWORD!| %JAVA% %ES_JAVA_OPTS% -Delasticsearch ^
endlocal
endlocal
exit /b %ERRORLEVEL%

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: I'm more than happy to remove this ugliness if we don't care about exiting with 0 (instead of an 1) when a user passes multiple --enrollment-token parameters

rem this hack is ugly but necessary because we can't exit with /b X from within the argument parsing loop.
rem exit 1 (without /b) would work for powershell but it will terminate the cmd process when run in cmd
:exitwithone
exit /b 1
8 changes: 5 additions & 3 deletions docs/java-rest/high-level/security/enroll_node.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ include-tagged::{doc-tests}/EnrollmentDocumentationIT.java[{api}-response]
for the HTTP layer, as a Base64 encoded string of the ASN.1 DER encoding of the key.
<2> The CA certificate that can be used by the new node in order to sign its certificate
for the HTTP layer, as a Base64 encoded string of the ASN.1 DER encoding of the certificate.
<3> The private key that the node can use for TLS for its transport layer, as a Base64
<3> The CA certificate that is used to sign the TLS certificate for the transport layer, as
a Base64 encoded string of the ASN.1 DER encoding of the certificate.
<4> The private key that the node can use for TLS for its transport layer, as a Base64
encoded string of the ASN.1 DER encoding of the key.
<4> The certificate that the node can use for TLS for its transport layer, as a Base64
<5> The certificate that the node can use for TLS for its transport layer, as a Base64
encoded string of the ASN.1 DER encoding of the certificate.
<5> A list of transport addresses in the form of `host:port` for the nodes that are already
<6> A list of transport addresses in the form of `host:port` for the nodes that are already
members of the cluster.


Expand Down
1 change: 1 addition & 0 deletions qa/os/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ plugins {
dependencies {
testImplementation project(':server')
testImplementation project(':libs:elasticsearch-core')
testImplementation(testArtifact(project(':x-pack:plugin:core')))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that we can use EnrollmentToken class in the qa tests

testImplementation "junit:junit:${versions.junit}"
testImplementation "org.hamcrest:hamcrest:${versions.hamcrest}"
testImplementation "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
Expand Down
Loading