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

Display security auto-configuration with fancy unicode #82740

Merged

Conversation

albertzaharovits
Copy link
Contributor

@albertzaharovits albertzaharovits commented Jan 18, 2022

TODO:
* detect if the banner PrintStream encoding supports the fancy unicode codepoints (otherwise, fallback to simpler variants)
* detect (expose) the terminal width, in order to construct the border to fill the width of the terminal
* make sure information doesn't use jansi when it is disabled (there are multiple ways to disable jansi)


Edited 24.01.2022

This PR slightly improves the format of the security auto-configuration information, which is printed on the terminal when
the initial cluster node first starts up.

It uses eye-catching Unicode characters for bullet points.
It also uses Unicode to display a continuous border, for the whole width of the terminal, before and after the information.
In addition, it uses ANSI escape sequences to render some of the information in bold fonts.

It will fallback to using regular characters if the JVM is set-up with a non-UTF encoding for the standard out.

Related: #82364

@albertzaharovits
Copy link
Contributor Author

FWIW here are some sample outputs, for the time being, with a large terminal width:

Vanilla configuration (when no node enrollment token is generated):
Capture d’écran 2022-01-18 à 18 04 18

When the enrollment token is generated (because network.host: "0.0.0.0"):
Capture d’écran 2022-01-18 à 18 12 27

cc @jkakavas @bytebilly @lockewritesdocs

@albertzaharovits albertzaharovits added :Security/Security Security issues without another label v8.0.0 >bug labels Jan 18, 2022
@albertzaharovits albertzaharovits changed the title Unicode auto-configuration display Display security auto-configuration with fancy unicode Jan 18, 2022
@jkakavas
Copy link
Member

Looks good to me @albertzaharovits thanks! I think this moves the needle quite a bit, helping the output to stand out. I'd only suggest a few more (5?10?) empty lines before and after to make it more pronounced that this is a standalone section and not logs

@jkakavas
Copy link
Member

This is how it looks on my machine and with a darker background

dark

@bytebilly
Copy link
Contributor

Thanks Albert, looks good!
I'm not sure what happens on "old" terminals or similar ones that don't support fancy output, do you have an idea?

@albertzaharovits
Copy link
Contributor Author

@bytebilly

I'm not sure what happens on "old" terminals or similar ones that don't support fancy output, do you have an idea?

I still need to implement a fallback for that, as per:

detect if the banner PrintStream encoding supports the fancy unicode codepoints (otherwise, fallback to simpler variants)

More exactly the issue is whether the JVM's character encoding that's used to print the information to the terminal "can encode" the special unicode code points (this is what I need to code still), eg UTF-8 can, Latin-1 can not.

But even in the case that the JVM is favorably configured, there is still some potential for funny characters (ie boxes and question marks):

  • if the terminal is configured with a different "locale" from the ES JVM
  • if the installed font doesn't accurately represent the glyphs (eg the "info" box in Ioannis' linux print screen, is very different than what I get on my mac).

The above two we cannot detect.

@albertzaharovits albertzaharovits marked this pull request as ready for review January 24, 2022 11:59
@elasticmachine elasticmachine added the Team:Security Meta label for security team label Jan 24, 2022
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

@albertzaharovits
Copy link
Contributor Author

Things I've noticed in the message, that maybe we could improve:

  • In the instruction on running docker ES nodes: docker run --name <node-name> -p <host-http-port>:9200 --net elastic -e "ENROLLMENT_TOKEN=<token>" docker.elastic.co/elasticsearch/elasticsearch:8.1.0 , the --name <node-name> -p <host-http-port>:9200 --net elastic part is not strictly necessary, the options are maybe relevant in the scenarios in the docs, but in my context they look like an unnecessary complication.
  • No equivalent docker command is displayed for running Kibana in docker.
  • Adding other ES nodes requires adjusting the network.host, or transport.host setting before starting the node with the enrollment token, but this is omitted (prob intentionally) from the instructions.

@jkakavas
Copy link
Member

  • In the instruction on running docker ES nodes: docker run --name -p :9200 --net elastic -e "ENROLLMENT_TOKEN=" docker.elastic.co/elasticsearch/elasticsearch:8.1.0 , the --name -p :9200 --net elastic part is not strictly necessary, the options are maybe relevant in the scenarios in the docs, but in my context they look like an unnecessary complication.

Agreed. I think that part of the struggle here is to add just enough information. We don't want to replicate the entirety of a relevant docs page but we do want to add some information that we believe is helpful. I was wary of adding anything related to docker but if we're not able to determine whether we're running in Docker and given the % of folks that will run this in Docker , I'm ++ to having something there. I agree with your suggestion to simplify the command though, maybe simply docker run -e "ENROLLMENT_TOKEN=<token>" docker.elastic.co/elasticsearch/elasticsearch:8.1.0 is enough ?

  • No equivalent docker command is displayed for running Kibana in docker.

Personally this falls into the too much information category for the startup message but I'm happy to change my mind.

  • Adding other ES nodes requires adjusting the network.host, or transport.host setting before starting the node with the enrollment token, but this is omitted (prob intentionally) from the instructions.

Yes this is a tricky one. We could assume that if the initial node is bound to not localhost, then the other nodes will be on other hosts for sure and so they'd need to change network.host or transport.host and print a relevant message, or prefix this with an if.. but then again this sounds like a documentation page to me. Interested to here other thoughts on the matter though

@jkakavas
Copy link
Member

jkakavas commented Jan 24, 2022

Yes this is a tricky one. We could assume that if the initial node is bound to not localhost, then the other nodes will be on other hosts for sure and so they'd need to change network.host or transport.host and print a relevant message, or prefix this with an if.. but then again this sounds like a documentation page to me. Interested to here other thoughts on the matter though

@bytebilly had caught this in the feature assurance doc but we failed to address this. :doh: I think we should treat it as a bug and fix it. We get the transport addresses from the node we call out to during enrollment and we figure out all IP Addresses we can know of ( for the SANs ) so we could possibly set transport.host to site IF any of the IP addresses that we get as existing cluster members is not in the ones we figured out for the host. I'll open a small PR

Copy link
Member

@jkakavas jkakavas left a comment

Choose a reason for hiding this comment

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

Output looks much nicer, added some suggestions and comments but LGTM in general. Happy to discuss some more about text etc but we can always iterate, this moves the needle significantly already!

assertThat(console.width().get(), is(width));
}
}

Copy link
Member

Choose a reason for hiding this comment

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

Is there a test we can write that would fail if tryExtractPrintCharset fails with a reflection related error ? Could be useful for upgrades

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I don't have good ideas. The method would fail if the classes in the JANSI lib change structure, following an upgrade, but we can't simulate that in a test.

We do not have tests asserting the auto-configuration message to the terminal.
If we would, we could assert the unicode formatting on at least some platforms.

Copy link
Member

Choose a reason for hiding this comment

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

We assert the message to the terminal in ArchiveGenerateInitialCredentialsTests for some simple things but we need to adjust and fix these tests ( currently muted ) and we can add additional cases for sure

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good, I missed those!

Copy link
Contributor Author

@albertzaharovits albertzaharovits Jan 24, 2022

Choose a reason for hiding this comment

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

TBC, when those tests are unmuted, I believe we can assert there that the displayed information contains unicode chars (on some platforms, eg not Windows), which also implies that reflection worked.

@albertzaharovits
Copy link
Contributor Author

Okay, this is what it looks like after the above suggestions:
Capture d’écran 2022-01-24 à 17 05 50

Unless @lockewritesdocs has other suggestions, I'm going to merge this as is.

FWIW we also add color to the text.

@albertzaharovits
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/part-2-fips

@lockewritesdocs
Copy link
Contributor

Unless @lockewritesdocs has other suggestions, I'm going to merge this as is.

I agree with @jkakavas in his previous comment. I do think that we need a separate line for enrolling a new node in Docker, but just enough to get the user up and running. This is only a startup message, and we'll rely on the documentation for more instructive, how-to information.

No equivalent docker command is displayed for running Kibana in docker.

I'm torn on this one. For many users, the current startup message will meet their needs -- they're able to start Elasticsearch with security enabled and can enroll additional nodes. I agree with @jkakavas that we don't want to clutter the startup message unnecessarily, but would we consider adding a link to the docs for Installing Kibana in Docker, which includes the necessary steps? For example:

If you're running in Docker, copy the enrollment token and run:
docker run -e \"ENROLLMENT_TOKEN=<token>\" docker.elastic.co/elasticsearch/elasticsearch:<version>

To enroll Kibana, refer to https://www.elastic.co/guide/en/kibana/8.0/docker.html.

@jkakavas
Copy link
Member

but would we consider adding a link to the docs for Installing Kibana in Docker, which includes the necessary steps? For example:

My personal preference would be to not add this.
If we're adding any links here, I'd much rather simplify the existing text even more and then add a link to a ( still simple but longer than can fit in a startup message single ) doc page, but we can iterate on this in a follow up

@lockewritesdocs
Copy link
Contributor

My personal preference would be to not add this.

I'm 👍 with not adding the link. Just wanted to have the discussion and see where we landed.

Copy link
Contributor

@lockewritesdocs lockewritesdocs left a comment

Choose a reason for hiding this comment

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

👍 @albertzaharovits! Much easier to scan and read.

@albertzaharovits
Copy link
Contributor Author

For test failure https://elasticsearch-ci.elastic.co/job/elastic+elasticsearch+pull-request+part-2-fips/361/ I've raised #82977 . Will be merging this after that.

@albertzaharovits
Copy link
Contributor Author

@elasticmachine update branch

@albertzaharovits albertzaharovits merged commit 6687a28 into elastic:master Jan 25, 2022
@albertzaharovits albertzaharovits deleted the unicode-banner-display branch January 25, 2022 09:00
albertzaharovits added a commit to albertzaharovits/elasticsearch that referenced this pull request Jan 25, 2022
This PR slightly improves the format of the security auto-configuration
information that is printed on the terminal when the initial cluster
node first starts up.

It uses eye-catching Unicode characters for bullet points.
It also uses Unicode to display a continuous border, for the whole
width of the terminal, before and after the information. In addition,
it uses ANSI escape sequences to render some of the information
in bold fonts.

It will fallback to using regular characters if the JVM is set-up with
a non-UTF encoding for the standard out.
@jkakavas
Copy link
Member

I realized ( late enough :) ) that we might want to add some more whitespace after the unicode characters so that it looks better in many terminals. Easy to do in a short followup though :
dark2

albertzaharovits added a commit that referenced this pull request Jan 25, 2022
This PR slightly improves the format of the security auto-configuration
information that is printed on the terminal when the initial cluster
node first starts up.

It uses eye-catching Unicode characters for bullet points.
It also uses Unicode to display a continuous border, for the whole
width of the terminal, before and after the information. In addition,
it uses ANSI escape sequences to render some of the information
in bold fonts.

It will fallback to using regular characters if the JVM is set-up with
a non-UTF encoding for the standard out.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Security/Security Security issues without another label Team:Security Meta label for security team v8.0.0-rc2 v8.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants