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

[HTTP] Add support for configuring a CDN (part I) #169408

Merged
merged 21 commits into from
Oct 21, 2023

Conversation

jloleysens
Copy link
Contributor

@jloleysens jloleysens commented Oct 19, 2023

Summary

This PR prepares the Kibana core code for configuring and using a CDN to serve the vast majority of assets.

Goals

(1) Configure a CDN URL: server.cdn.url
(2) Reach a new domain: updating our CSP to allow this
(3) Serve JS bundles, CSS, fonts via CDN

How to test

  1. Make a release/distribution build of Kibana (node ./scripts/build.js --release --skip-os-packages), will output to ./build/kibana.
  2. Edit /etc/hosts
    1. I added 127.0.0.1 my.cdn.test
  3. Edit config/kibana.dev.yml adding server.cdn.url: "http://my.cdn.test:1772"
  4. cd into build/kibana once the release build is done
  5. Download and run this (hacky) script there. It should (🤞🏻 ) create a folder structure mirroring our server paths: https://gist.github.com/jloleysens/86cae7ea3d7512e6a6e92cebbf1566f4
  6. Start a file server in build/kibana. For example: npx http-server -p 1772 --cors --gzip --brotli -- this will be the "CDN" server
  7. Start Kibana yarn start and ES yarn es snapshot
  8. Open Kibana, checking the Network tab of your browser for anything that fails to load: 404s, CORs or CSP is almost definitely a bug in this code.

Future work

  • Include the translations file to the CDN (should not be much effort)
  • Update the build process to create a folder structure that mirrors what we serve from Kibana today, this will replace step 5 in the testing process
    • This includes deploying new assets to the CDN as part of our promotion pipeline

Screenshots

Screenshot 2023-10-19 at 17 38 56

Checklist

Delete any items that are not applicable to this PR.

Risk Matrix

Delete this section if it is not applicable to this PR.

Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release.

When forming the risk matrix, consider some of the following examples and how they may potentially impact the change:

Risk Probability Severity Mitigation/Notes
Changing the existing behaviour med high based on the existing test coverage I expect us to not change the current non-CDN asset serving
Use of undocumented feature Very low Low While this could brick Kibana, it would be a simple configuration change

For maintainers

@jloleysens jloleysens added Feature:http Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc release_note:skip Skip the PR/issue when compiling release notes v8.12.0 labels Oct 19, 2023
@jloleysens jloleysens requested a review from a team as a code owner October 19, 2023 14:42
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

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

This looks like a great foundation to start iterating on. Something we should explore with operations is how to write a smoke test for this as a bug here would be high impact. Would be great if once we've published assets we could spin up Kibana and make sure it can render from the CDN.

Comment on lines 38 to 45
default_src: [hostname],
font_src: [hostname],
img_src: [hostname],
script_src: [hostname],
style_src: [hostname],
worker_src: [hostname],
connect_src: [hostname],
frame_src: [hostname],
Copy link
Contributor

Choose a reason for hiding this comment

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

@elastic/kibana-security IIRC you've always reviewed changes to our CSP so would be good to get a +1 from you

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

Just a few remarks and question, but overall LGTM

Comment on lines +114 to +124
export type CspAdditionalConfig = Pick<
Partial<CspConfigType>,
| 'connect_src'
| 'default_src'
| 'font_src'
| 'frame_src'
| 'img_src'
| 'script_src'
| 'style_src'
| 'worker_src'
>;
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: I would just have gone with Partial<CspConfigType>, but what you did is probably better 😄

Copy link
Contributor Author

@jloleysens jloleysens Oct 19, 2023

Choose a reason for hiding this comment

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

Yeah, I had that initially, but there is other funky stuff in there and I wanted scope the overrides to just the policy directives

Comment on lines 49 to 51
public static from(input: Input = {}) {
return new CdnConfig(input);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: FMI, what's the upside of the private constructor + static creator? (or maybe that's just how we're already doing with other http sub configs?)

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 q, I slightly refactored this, bc I realised I was using Input in both the constructor and in this state creator. The constructor know uses it's own, separated args as they are IMO easier to use in the constructor.

But yeah, not massive benefit, as you point out.

Comment on lines +216 to 217
// TODO: Make this load as part of static assets!
translationsUrl: `${basePath}/translations/${i18n.getLocale()}.json`,
Copy link
Contributor

Choose a reason for hiding this comment

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

++ (but good luck 😄)

Comment on lines 38 to 45
default_src: [hostname],
font_src: [hostname],
img_src: [hostname],
script_src: [hostname],
style_src: [hostname],
worker_src: [hostname],
connect_src: [hostname],
frame_src: [hostname],
Copy link
Member

Choose a reason for hiding this comment

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

Have you verified that Kibana requires all of these declarations for the CDN to function? A few initial thoughts:

  1. We don't supply a default_src today, and I don't think the CDN should be the first to do so, unless there's a compelling reason.
  2. Will Kibana host frames whose src points to the CDN? If not, then we likely don't need frame_src.
  3. This CDN will (I assume) host static assets. It seems unlikely that connect_src would be required.
  4. Will the CDN be hosting scripts used by web workers? If not, then worker_src is unlikely to be required. I don't know where we're using working within Kibana today, so this is a genuine question.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All valid points :) there is some amount of unknown, since I don't know what all will be served from the CDN, but:

  1. Sounds good to me!
  2. I don't know, but we can remove for now
  3. I believe we do have script based loading of certain assets
  4. We will be hosting Monaco editor's worker scripts on the CDN, yes

@jbudz
Copy link
Member

jbudz commented Oct 19, 2023

Do we think falling back to local assets if the CDN is down is worthwhile?

@jloleysens
Copy link
Contributor Author

jloleysens commented Oct 20, 2023

Do we think falling back to local assets if the CDN is down is worthwhile?

Sounds worthwhile to me, probably as an enhancement to this first iteration. There are two failure scenarios I can think of:

  1. The CDN is down/unavailable
  2. The CDN does not have assets deployed (404s), perhaps our deployment failed and we notice to late

To address both of these are you imagining something like this:

https://stackoverflow.com/a/2607534

Perhaps webpack already has something for this?

@jloleysens
Copy link
Contributor Author

@jbudz

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/core-http-server-internal 52 53 +1
@kbn/core-http-server-mocks 42 43 +1
total +2

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
@kbn/core-http-server-internal 6 7 +1
Unknown metric groups

API count

id before after diff
@kbn/core-http-server-internal 58 59 +1
@kbn/core-http-server-mocks 43 44 +1
total +2

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@jloleysens jloleysens merged commit 8727c68 into elastic:main Oct 21, 2023
30 checks passed
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Oct 21, 2023
@jloleysens jloleysens deleted the introduce-cdn-as-config-and-use-it branch October 21, 2023 13:40
benakansara pushed a commit to benakansara/kibana that referenced this pull request Oct 22, 2023
benakansara pushed a commit to benakansara/kibana that referenced this pull request Oct 22, 2023
`${regularBundlePath}/kbn-ui-shared-deps-src/${UiSharedDepsSrc.cssDistFilename}`,
`${basePath}/ui/legacy_light_theme.min.css`,
`${bundlesHref}/kbn-ui-shared-deps-src/${UiSharedDepsSrc.cssDistFilename}`,
`${baseHref}/ui/legacy_light_theme.min.css`,
Copy link
Member

Choose a reason for hiding this comment

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

Have we considered putting this route behind the build number? Behind a CDN I'm not sure how would push updates through to these files.

jbudz added a commit that referenced this pull request Nov 6, 2023
Closes #169427

Adds a new build step `createCdnAssets` that will create an archive
`kibana-<version>-cdn-assets.tar.gz` with static assets organized using
the request structure of the kibana client.

- By default CDN assets are created
- Adding the flag `node scripts/build --skip-cdn-assets` will skip
creation
- `ci:build-cdn-assets` can be used to create and upload the archive for
testing

Testing: see #169408. Builds are
available in the artifacts tab on the `Build Distribution` step.

1) Extract builds
2) ```
python3 -m http.server -b localhost -d kibana-8.12.0-SNAPSHOT-cdn-assets
8000
    ```
3) ```
echo 'server.cdn.url: http://localhost:8000' >>
kibana-8.12.0-SNAPSHOT/config/kibana.yml
    ```
4) ```
   kibana-8.12.0-SNAPSHOT/bin/kibana
   ```
jloleysens added a commit that referenced this pull request Feb 7, 2024
## Summary

Follow up of [first CDN
PR](#169408). Primary focus is
replacing our build nr with SHA that allows cache busting and maintains
anti-collision properties.

## How to test

Start Kibana as usual navigating around the app with the network tab
open in your browser of choice. Keep an eye out for any asset loading
errors. It's tricky to test every possible asset since there are many
permutations, but generally navigating around Kibana should work exactly
as it did before regarding loading bundles and assets.

## Notes
* did a high-level audit of usages of `buildNum` in `packages`, `src`
and `x-pack` adding comments where appropriate.
* In non-distributable builds (like dev) static asset paths will be
prefixed with `XXXXXXXXXXXX` instead of Node's `Number.MAX_SAFE_INTEGER`
* Added some validation to ensure the CDN url is of the expected form:
nothing trailing the pathname

### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### Risk Matrix

| Risk | Probability | Severity | Mitigation/Notes |

|---------------------------|-------------|----------|-------------------------|
| We break some first or third party dependencies on existing asset
routes | Med | High | Attempting to mitgate by serving static assets
from both old and new paths where paths have updated to include the
build SHA. Additioanlly: it is very bad practice to rely on the values
of the static paths, but someone might be |
| Cache-busting is more aggressive | High | Low | Unlikely to be a big
problem, but we are not scoping more static assets to a SHA and so every
new Kibana release will require clients to, for example, download fonts
again. |


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
fkanout pushed a commit to fkanout/kibana that referenced this pull request Feb 7, 2024
…ic#175898)

## Summary

Follow up of [first CDN
PR](elastic#169408). Primary focus is
replacing our build nr with SHA that allows cache busting and maintains
anti-collision properties.

## How to test

Start Kibana as usual navigating around the app with the network tab
open in your browser of choice. Keep an eye out for any asset loading
errors. It's tricky to test every possible asset since there are many
permutations, but generally navigating around Kibana should work exactly
as it did before regarding loading bundles and assets.

## Notes
* did a high-level audit of usages of `buildNum` in `packages`, `src`
and `x-pack` adding comments where appropriate.
* In non-distributable builds (like dev) static asset paths will be
prefixed with `XXXXXXXXXXXX` instead of Node's `Number.MAX_SAFE_INTEGER`
* Added some validation to ensure the CDN url is of the expected form:
nothing trailing the pathname

### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### Risk Matrix

| Risk | Probability | Severity | Mitigation/Notes |

|---------------------------|-------------|----------|-------------------------|
| We break some first or third party dependencies on existing asset
routes | Med | High | Attempting to mitgate by serving static assets
from both old and new paths where paths have updated to include the
build SHA. Additioanlly: it is very bad practice to rely on the values
of the static paths, but someone might be |
| Cache-busting is more aggressive | High | Low | Unlikely to be a big
problem, but we are not scoping more static assets to a SHA and so every
new Kibana release will require clients to, for example, download fonts
again. |


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
…ic#175898)

## Summary

Follow up of [first CDN
PR](elastic#169408). Primary focus is
replacing our build nr with SHA that allows cache busting and maintains
anti-collision properties.

## How to test

Start Kibana as usual navigating around the app with the network tab
open in your browser of choice. Keep an eye out for any asset loading
errors. It's tricky to test every possible asset since there are many
permutations, but generally navigating around Kibana should work exactly
as it did before regarding loading bundles and assets.

## Notes
* did a high-level audit of usages of `buildNum` in `packages`, `src`
and `x-pack` adding comments where appropriate.
* In non-distributable builds (like dev) static asset paths will be
prefixed with `XXXXXXXXXXXX` instead of Node's `Number.MAX_SAFE_INTEGER`
* Added some validation to ensure the CDN url is of the expected form:
nothing trailing the pathname

### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### Risk Matrix

| Risk | Probability | Severity | Mitigation/Notes |

|---------------------------|-------------|----------|-------------------------|
| We break some first or third party dependencies on existing asset
routes | Med | High | Attempting to mitgate by serving static assets
from both old and new paths where paths have updated to include the
build SHA. Additioanlly: it is very bad practice to rely on the values
of the static paths, but someone might be |
| Cache-busting is more aggressive | High | Low | Unlikely to be a big
problem, but we are not scoping more static assets to a SHA and so every
new Kibana release will require clients to, for example, download fonts
again. |


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
…ic#175898)

## Summary

Follow up of [first CDN
PR](elastic#169408). Primary focus is
replacing our build nr with SHA that allows cache busting and maintains
anti-collision properties.

## How to test

Start Kibana as usual navigating around the app with the network tab
open in your browser of choice. Keep an eye out for any asset loading
errors. It's tricky to test every possible asset since there are many
permutations, but generally navigating around Kibana should work exactly
as it did before regarding loading bundles and assets.

## Notes
* did a high-level audit of usages of `buildNum` in `packages`, `src`
and `x-pack` adding comments where appropriate.
* In non-distributable builds (like dev) static asset paths will be
prefixed with `XXXXXXXXXXXX` instead of Node's `Number.MAX_SAFE_INTEGER`
* Added some validation to ensure the CDN url is of the expected form:
nothing trailing the pathname

### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### Risk Matrix

| Risk | Probability | Severity | Mitigation/Notes |

|---------------------------|-------------|----------|-------------------------|
| We break some first or third party dependencies on existing asset
routes | Med | High | Attempting to mitgate by serving static assets
from both old and new paths where paths have updated to include the
build SHA. Additioanlly: it is very bad practice to rely on the values
of the static paths, but someone might be |
| Cache-busting is more aggressive | High | Low | Unlikely to be a big
problem, but we are not scoping more static assets to a SHA and so every
new Kibana release will require clients to, for example, download fonts
again. |


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
jbudz added a commit that referenced this pull request Feb 22, 2024
Adds support for setting `server.cdn.url` in our docker containers.
Implemented at #169408.
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Feb 22, 2024
Adds support for setting `server.cdn.url` in our docker containers.
Implemented at elastic#169408.

(cherry picked from commit 023f5d6)
kibanamachine added a commit that referenced this pull request Feb 22, 2024
# Backport

This will backport the following commits from `main` to `8.13`:
- [[bin/kibana-docker] Add server.cdn.url
(#177491)](#177491)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT
[{"author":{"name":"Jon","email":"jon@elastic.co"},"sourceCommit":{"committedDate":"2024-02-22T01:05:08Z","message":"[bin/kibana-docker]
Add server.cdn.url (#177491)\n\nAdds support for setting
`server.cdn.url` in our docker containers.\r\nImplemented at
#169408
Add
server.cdn.url","number":177491,"url":"#177491
Add server.cdn.url (#177491)\n\nAdds support for setting
`server.cdn.url` in our docker containers.\r\nImplemented at
#169408
Add server.cdn.url (#177491)\n\nAdds support for setting
`server.cdn.url` in our docker containers.\r\nImplemented at
#169408"}}]}]
BACKPORT-->

Co-authored-by: Jon <jon@elastic.co>
fkanout pushed a commit to fkanout/kibana that referenced this pull request Mar 4, 2024
…ic#175898)

## Summary

Follow up of [first CDN
PR](elastic#169408). Primary focus is
replacing our build nr with SHA that allows cache busting and maintains
anti-collision properties.

## How to test

Start Kibana as usual navigating around the app with the network tab
open in your browser of choice. Keep an eye out for any asset loading
errors. It's tricky to test every possible asset since there are many
permutations, but generally navigating around Kibana should work exactly
as it did before regarding loading bundles and assets.

## Notes
* did a high-level audit of usages of `buildNum` in `packages`, `src`
and `x-pack` adding comments where appropriate.
* In non-distributable builds (like dev) static asset paths will be
prefixed with `XXXXXXXXXXXX` instead of Node's `Number.MAX_SAFE_INTEGER`
* Added some validation to ensure the CDN url is of the expected form:
nothing trailing the pathname

### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### Risk Matrix

| Risk | Probability | Severity | Mitigation/Notes |

|---------------------------|-------------|----------|-------------------------|
| We break some first or third party dependencies on existing asset
routes | Med | High | Attempting to mitgate by serving static assets
from both old and new paths where paths have updated to include the
build SHA. Additioanlly: it is very bad practice to rely on the values
of the static paths, but someone might be |
| Cache-busting is more aggressive | High | Low | Unlikely to be a big
problem, but we are not scoping more static assets to a SHA and so every
new Kibana release will require clients to, for example, download fonts
again. |


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
fkanout pushed a commit to fkanout/kibana that referenced this pull request Mar 4, 2024
Adds support for setting `server.cdn.url` in our docker containers.
Implemented at elastic#169408.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:http release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v8.12.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants