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

Migrate Console to use Node http instead of Hapi to support GET requests with bodies #46200

Merged
merged 13 commits into from
Sep 30, 2019

Conversation

cjcenizal
Copy link
Contributor

@cjcenizal cjcenizal commented Sep 19, 2019

Fixes #11125. Replaces #39170.

Summary

This approach uses Node's http library. It contains an earlier commit which used the request library.

Considerations

Effects upon users with read-only permissions

Per #36635 ("Autocomplete support for read only users"), some admins limit users to read-only access of a few select indices. How does this change affect the experience of users with these limited permissions? I would expect these users to experience problems due to their GET requests being converted to POST requests on master, and that these changes would address this problem.

Support for streaming large responses

How are large responses handled on master? Are they streamed? If so then we need to ensure this behavior is unaffected by these changes.

DONE: Auth header is sent with ES request

I verified that the required auth header is passed along by trying to access an index to which the user didn't have permission.

image
image

DONE: Correct error response is shown when ES is down

When ES is unavailable, the request to HEAD /?pretty=true should resolve in:

{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Unauthorized"
}

DONE: HEAD requests behave as expected

Create a document and then send a HEAD request for it.

POST twitter/_doc/0
{ "a": "b" }

HEAD twitter/_doc/0

Expected response:

200 - OK

DONE: JSON parse failures are returned

Create a document with an incorrectly formed payload.

POST twitter/_doc/0
{
  "a:" "b"
}

Expected response:

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "failed to parse"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "failed to parse",
    "caused_by": {
      "type": "json_parse_exception",
      "reason": "Unexpected character ('\"' (code 34)): was expecting a colon to separate field name and value\n at [Source: org.elasticsearch.common.bytes.BytesReference$MarkSupportingStreamInputWrapper@4dc2f408; line: 2, column: 9]"
    }
  },
  "status": 400
}

DONE: SSL/TLS is still supported

Tested with an SSL setup and verified everything works as normal.

Figure out what rejectUnauthorized was supposed to do

The rejectUnauthorized variable was originally an option passed to Hapi, introduced in https://github.com/elastic/kibana/pull/10611/files. What did it do? Do we still need it?

DONE: DELETE requests should support bodies

This is needed by the scroll API.

DONE: cat API responses still support formatting

Send a [cat](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat.html] request with formatting enabled:

GET _cat/master?v

Expect a response formatted like this:

id                     host      ip        node
WgJsUc7lQjiFR9oX9HU6MA 127.0.0.1 127.0.0.1 CJs-MacBook-Pro.attlocal.net

DONE: GET requests which don't support bodies are rejected

Some APIs don't support bodies with GET requests and we still need to make sure they're being rejected.

GET twitter/_doc/0
{
  "a": "b"
}

On master this will act as a POST and create a document, but it should be an error:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "request [GET /twitter/_doc/0] does not support having a body"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "request [GET /twitter/_doc/0] does not support having a body"
  },
  "status": 400
}

proxyConfig and proxyFilters should still work

We should remove these settings for 8.0 (#39494), but for 7.x they're still supported. For more information on them see the 5.0 console docs.

@@ -105,42 +103,54 @@ export const createProxyRoute = ({
const { path, method } = query;
const uri = resolveUri(baseUrl, path);

// Because this can technically be provided by a settings-defined proxy config, we need to
// preserve these property names to maintain BWC.
const { timeout, rejectUnauthorized, agent, headers } = getConfigForReq(req, uri);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that rejectUnauthorized and agent are currently not being consumed. We should verify what kind of behavior depended upon them originally and ensure that behavior still exists.

… requests with bodies.

- Remove payload configuration of endpoint.
@cjcenizal cjcenizal force-pushed the console/support-get-requests branch from b88fe9d to 254c605 Compare September 19, 2019 23:48
@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal cjcenizal added Feature:Console Dev Tools Console Feature Feature:Dev Tools release_note:fix Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v7.5.0 v8.0.0 labels Sep 20, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/es-ui

@elasticmachine
Copy link
Contributor

💔 Build Failed

Removed some whitespace
Converted Elasticsearch proxy config to TS (now we can see the types with https.AgentOptions)
Wrap request in util.promisify and refactor
Use 'url' lib for parsing URLs
Remove rejectUnauthorized from proxy_route.js (this is a TLS setting handled in agent setup)
@jloleysens
Copy link
Contributor

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@jloleysens jloleysens marked this pull request as ready for review September 24, 2019 17:03
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@jloleysens
Copy link
Contributor

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@jbudz
Copy link
Member

jbudz commented Sep 27, 2019

+1 on the non request implementation, ref request/request#3142. It looks like it's not used but still in the title/description

headers: {
...headers,
'content-type': 'application/json',
'transfer-encoding': 'chunked',
Copy link
Member

Choose a reason for hiding this comment

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

👍

Copy link
Member

Choose a reason for hiding this comment

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

i don't feel very strongly about this, but think it's fine. the query may have a lot of data, but i would expect the ui to lock up before that's an issue. ace used to have a max of 65k lines but i'm a little out of date

Copy link
Contributor Author

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

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

LGTM @jloleysens! I had some nitpicks on the code, but feel free to ignore them. I tested locally and marked everything with "DONE" that I was able to verify. Here are the things I haven't looked into because they're not things I'm familiar with:

  • Effects upon users with read-only permissions: we could possibly ignore this one since I was just pointing out that this change may actually address the reported issue
  • Support for streaming large responses: from @jbudz's comment it sounds like streaming is not actually a concern?
  • Figure out what rejectUnauthorized was supposed to do: not sure if it's worth digging into this since auth seems to behave as expected
  • proxyConfig and proxyFilters should still work: this is worth some light testing -- these features are deprecated and we stopped documenting them with 6.x, but we don't want to break things for anyone who still happens to be using this

headers: http.OutgoingHttpHeaders;
}

// We use a modified version of Hapi's Wreck because Hapi, Axios, and Superagent don't support GET requests
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nit: got an extra space between "because" and "Hapi"

import { URL } from 'url';

interface Args {
method: string;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nit: Should we change this to match https://github.com/elastic/kibana/pull/46570/files#diff-66fd5f9b6470ae3554f659cf3f40fe1dR24 ?

method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head';

const req = client.request({
method: method.toUpperCase(),
host: uri.hostname,
port: uri.port !== '' ? Number(uri.port) : undefined,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nit: I think this would be easier to scan if we avoid the negative comparison:

port: uri.port === '' ? undefined : Number(uri.port),

host: uri.hostname,
port: uri.port !== '' ? Number(uri.port) : undefined,
protocol: uri.protocol,
path: `${uri.pathname}${uri.search || ''}`,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nit: the code might be easier to scan if we destructure all of these uri properties on line 40, so we don't need to keep referring to it.

@jloleysens jloleysens changed the title Migrate Console to use request library instead of Hapi to support GET requests with bodies Migrate Console to use node http instead of Hapi to support GET requests with bodies Sep 30, 2019
@jloleysens jloleysens changed the title Migrate Console to use node http instead of Hapi to support GET requests with bodies Migrate Console to use Node http instead of Hapi to support GET requests with bodies Sep 30, 2019
@jloleysens
Copy link
Contributor

@cjcenizal

Thanks for looking through and doing manual testing! I can confirm on the points you did not test:

  • I think this should address GETs with bodies. Which, to my understanding, should address the perms issues
  • I was slightly concerned that transfer-encoding header might not be compatible with what people are running in the wild. But it looks like this is a safe setting and should be the default fallback in current master too. I still think piping through incoming ES response streams is the behaviour we want here and shouldn't be an issue.
  • rejectUnauthorized is used in Wreck to create an http(s) agent with specific behaviour for throwing under certain conditions when an agent isn't provided or as an explicit per request override. The way we are setting up agents already does this legwork and so the behaviour is the same as before in this regard. I did notice that we weren't respecting setting this value via the legacy/deprecated proxy config so have re-enabled this.
  • Did a manual test with proxy config (set up a config to my local ES instance) and confirmed that it was work through that path too.

@jloleysens
Copy link
Contributor

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@cjcenizal cjcenizal merged commit 3316d44 into elastic:master Sep 30, 2019
@cjcenizal cjcenizal deleted the console/support-get-requests branch September 30, 2019 17:19
cjcenizal added a commit that referenced this pull request Sep 30, 2019
…sts with bodies (#46200) (#46953)

* Cleaned up use of es.send API
  - Converted Elasticsearch proxy config to TS (now we can see the types with https.AgentOptions)
  - Wrap request in util.promisify and refactor
  - Use 'url' lib for parsing URLs
  - Remove rejectUnauthorized from proxy_route.js (this is a TLS setting handled in agent setup)
* Retained original proxying behavior
* Re-enable support for setting rejectUnauthorized via proxy config settings
* Updated tests.
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Console Dev Tools Console Feature Feature:Dev Tools release_note:fix Team:Kibana Management Dev Tools, Index Management, Upgrade Assistant, ILM, Ingest Node Pipelines, and more v7.5.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[console] GET with body acts as POST
4 participants