From a2c14064d1f977eb1852d871a65d1514b9913e83 Mon Sep 17 00:00:00 2001 From: miaawong Date: Tue, 24 Sep 2024 11:55:52 -0400 Subject: [PATCH 01/24] wip --- kurl_proxy/assets/images/check.svg | 4 + kurl_proxy/assets/insecure.html | 226 ++++- kurl_proxy/assets/output.css | 555 +++++++++++ kurl_proxy/assets/tls-custom.css | 304 ++++-- kurl_proxy/assets/tls.html | 261 +++-- kurl_proxy/assets/tls.js | 76 +- kurl_proxy/assets/welcome.html | 99 ++ kurl_proxy/cmd/main.go | 26 + web/src/Root.tsx | 888 +++++++++++------- web/src/components/PreflightResultPage.tsx | 16 +- .../apps/EmbeddedClusterManagement.tsx | 72 +- web/src/components/selection.json | 47 + .../upgrade_service/PreflightChecks.tsx | 2 +- .../AppConfig/components/AppConfig.tsx | 150 +-- .../scss/components/watches/WatchConfig.scss | 4 +- 15 files changed, 2052 insertions(+), 678 deletions(-) create mode 100644 kurl_proxy/assets/images/check.svg create mode 100644 kurl_proxy/assets/output.css create mode 100644 kurl_proxy/assets/welcome.html diff --git a/kurl_proxy/assets/images/check.svg b/kurl_proxy/assets/images/check.svg new file mode 100644 index 0000000000..e8bdd9e5dc --- /dev/null +++ b/kurl_proxy/assets/images/check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/kurl_proxy/assets/insecure.html b/kurl_proxy/assets/insecure.html index 3f15fc48a4..5ec3152495 100644 --- a/kurl_proxy/assets/insecure.html +++ b/kurl_proxy/assets/insecure.html @@ -1,95 +1,219 @@ - - - - + + + + TLS Warning | Admin Console + {{if .AppIcon }} - + {{end}} - -
-
+
+ +
+
+
+
+ + Let's get you started! + +
+
+ check + Secure the Admin Console +
+
+ check + + Configure the cluster (optional) + +
+
+ check + Configure {{.AppTitle}} +
+
+ check + + Validate the environment & Install {{.AppTitle}} + +
+
+
+

Secure the Admin Console

+
+
-

Bypass browser TLS warning

-

We use a self-signed SSL/TLS Certificate to secure the communication between your local machine and the Admin Console during setup. You'll see a warning about this in your browser, but you can be confident that this is secure.

+

Bypass browser TLS warning

+

+ We use a self-signed SSL/TLS Certificate to secure the + communication between your local machine and the Admin Console + during setup. You'll see a warning about this in your browser, but + you can be confident that this is secure. +

-

-

+

+ +

-
-
-

Verifying the certificate's authenticity

-
-                    
-                    
-                  
-
+ +
+ +
+
+

+ Click here to verify the + certificate's authenticity (optional) +

-
-
-

SHA Fingerprint

-
-                    {{ .fingerprintSHA1 }}
-                  
+
- -
-

- -

-
+
-
- -
+
+ diff --git a/kurl_proxy/assets/output.css b/kurl_proxy/assets/output.css new file mode 100644 index 0000000000..619203bbce --- /dev/null +++ b/kurl_proxy/assets/output.css @@ -0,0 +1,555 @@ +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +/* +! tailwindcss v3.4.13 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + letter-spacing: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} diff --git a/kurl_proxy/assets/tls-custom.css b/kurl_proxy/assets/tls-custom.css index 693ac23899..94fd52947b 100644 --- a/kurl_proxy/assets/tls-custom.css +++ b/kurl_proxy/assets/tls-custom.css @@ -3,48 +3,129 @@ License: none (public domain) */ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; } body { - line-height: 1; + line-height: 1; } -ol, ul { - list-style: none; +ol, +ul { + list-style: none; } -blockquote, q { - quotes: none; +blockquote, +q { + quotes: none; } -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ""; + content: none; } table { - border-collapse: collapse; - border-spacing: 0; + border-collapse: collapse; + border-spacing: 0; } body, @@ -71,7 +152,7 @@ body a { } .replicated-link { - color: #326DE6; + color: #326de6; cursor: pointer; font-weight: 500; } @@ -107,6 +188,7 @@ code { .hidden-input { opacity: 0; text-indent: -9999px; + position: absolute; } .insecure-image { @@ -145,29 +227,29 @@ code { } .notification.is-warning { - border-color: #BC4752; - color: #BC4752; - background-color: #FBECEA; + border-color: #bc4752; + color: #bc4752; + background-color: #fbecea; width: 250px; } .notification.is-success { border-color: #44bb66; color: #44bb66; - background-color: #EDFFF2; + background-color: #edfff2; } .notification.is-info { border-color: #073551; color: #073551; - background-color: #F5F8FC; + background-color: #f5f8fc; } .form-input { display: block; box-sizing: border-box; width: 100%; - border: 1px solid #DFDFDF; + border: 1px solid #dfdfdf; border-radius: 4px; outline: 0; font-size: 12px; @@ -175,13 +257,13 @@ code { line-height: normal; color: #323232; padding: 7px 12px 8px; - transition: border .2s; + transition: border 0.2s; height: 30px; } .form-input:active, .form-input:focus { - border-color: #326DE6; + border-color: #326de6; } .form-input.larger { @@ -191,18 +273,18 @@ code { .form-input.has-error, .form-input.has-error:focus, .form-input.has-error:active { - border-color: #EE5042; + border-color: #ee5042; } .form-input.is-disabled { user-select: none; cursor: not-allowed; - background-color: #F8F8F8; - border-color: #DFDFDF; + background-color: #f8f8f8; + border-color: #dfdfdf; color: #717171; } .form-input::placeholder { - color: #C4C7CA; + color: #c4c7ca; } .btn { @@ -214,24 +296,24 @@ code { display: inline-block; border: 0; border-radius: 3px; - transition: all .2s; + transition: all 0.2s; outline: none; position: relative; } .btn.primary { - background-color: #326DE6; + background-color: #326de6; border-width: 1px; border-style: solid; border-color: transparent; color: #ffffff; - -webkit-box-shadow: inset 0px -2px 0px 0px rgba(0,0,0,0.25); - -moz-box-shadow: inset 0px -2px 0px 0px rgba(0,0,0,0.25); - box-shadow: inset 0px -2px 0px 0px rgba(0,0,0,0.25); + -webkit-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.25); + -moz-box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.25); + box-shadow: inset 0px -2px 0px 0px rgba(0, 0, 0, 0.25); } .btn.primary:not(:disabled):hover { - background-color: #265BC7; + background-color: #265bc7; } .btn.primary.is-disabled, @@ -239,20 +321,17 @@ code { .btn.primary:disabled, .btn.primary[disabled] { cursor: not-allowed; - border-color: #A3D3E9; + border-color: #a3d3e9; color: #ffffff; - background-color: #A3D3E9; + background-color: #a3d3e9; } .btn.secondary { - background-color: #F6F6F6; + background-color: #fff; border-width: 1px; border-style: solid; - border-color: transparent; - color: #326DE6; - -webkit-box-shadow: inset 0px -2px 0px 0px rgba(0,0,0,0.25); - -moz-box-shadow: inset 0px -2px 0px 0px rgba(0,0,0,0.25); - box-shadow: inset 0px -2px 0px 0px rgba(0,0,0,0.25); + border-color: #326de6; + color: #326de6; } .text-muted { @@ -260,7 +339,7 @@ code { font-size: 12px; font-weight: 400; line-height: 20px; - color: #9B9B9B; + color: #9b9b9b; } button.text-button { @@ -269,7 +348,7 @@ button.text-button { padding: 0; cursor: pointer; display: inline-block; - color: #326DE6; + color: #326de6; margin-left: 15px; font-weight: 500; font-size: 12px; @@ -280,20 +359,22 @@ button.text-button:hover { } .flex { - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; } .flex-column { - display: flex; + display: flex; flex-direction: column; } -.flex-auto { flex: 0 0 auto; } +.flex-auto { + flex: 0 0 auto; +} .flex1 { - flex: 1; - min-height: 0; + flex: 1; + min-height: 0; } .flex-1-auto { - flex: 1 1 auto; + flex: 1 1 auto; } .u-minHeight--full { @@ -304,12 +385,16 @@ button.text-button:hover { width: 100%; } -.justifyContent--center { justify-content: center; } -.alignContent--center { align-content: center; } +.justifyContent--center { + justify-content: center; +} +.alignContent--center { + align-content: center; +} .borderWrapper { - width:660px; - box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.20); + width: 660px; + box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 20px; } @@ -361,7 +446,7 @@ button.text-button:hover { .tls-section-sub { font-size: 14px; font-weight: 400; - color: #9B9B9B; + color: #9b9b9b; line-height: 22px; margin-bottom: 15px; } @@ -369,7 +454,7 @@ button.text-button:hover { .tls-section-sub-sub { font-size: 12px; font-weight: 400; - color: #9B9B9B; + color: #9b9b9b; margin-bottom: 12px; } @@ -379,9 +464,9 @@ button.text-button:hover { .CodeSnippet .CodeSnippet-content { padding: 15px; - border: 1px solid #DFDFDF; + border: 1px solid #dfdfdf; border-radius: 4px; - background-color: #F5F8FC; + background-color: #f5f8fc; } .CodeSnippet .CodeSnippet-content p { @@ -397,7 +482,7 @@ button.text-button:hover { } .inputkey { - top: 40px; + top: 40px; left: 49px; overflow: hidden; position: absolute; @@ -410,11 +495,11 @@ button.text-button:hover { } .inputkey + label { - cursor: pointer; + cursor: pointer; } .inputcert { - top: 40px; + top: 40px; left: 70px; overflow: hidden; position: absolute; @@ -427,7 +512,7 @@ button.text-button:hover { } .inputcert + label { - cursor: pointer; + cursor: pointer; } .appIcon { @@ -442,12 +527,13 @@ button.text-button:hover { box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.3); } .hostname-hint { - color: red; - font-size: 12px; - padding: 2px 0; + color: red; + font-size: 12px; + padding: 2px 0; } -input[type="radio"], label { +input[type="radio"], +label { display: inline-block; font-family: "Helvetica Neue", "Helvetica", sans-serif; font-weight: 400; @@ -466,7 +552,51 @@ div.hidden { p.hidden { display: none; } -#key-label, #cert-label { +#key-label, +#cert-label { max-width: 240px; word-wrap: break-word; -} \ No newline at end of file +} + +.cert-type-box { + width: 150px; + height: 50px; + background: #fff; + border: 1px solid #326de6; + border-radius: 8px; + padding: 10px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +} + +.checked-background { + color: white; + background: #326de6; +} + +.NavBarWrapper { + width: 100%; + padding: 0 30px; + background-color: #ffffff; + box-shadow: 0 1px 0 #c4c8ca; + margin-bottom: 0; + z-index: 10; + display: flex; + align-items: center; + justify-content: space-between; + height: 50px !important; +} +.HeaderLogo { + margin-right: 20px; +} +.nav-logo { + height: 30px; + width: 30px; + background-position: center; + background-size: contain; + background-repeat: no-repeat; + background-color: #ffffff; + z-index: 1; +} diff --git a/kurl_proxy/assets/tls.html b/kurl_proxy/assets/tls.html index f2c8578d1e..40100e9b3c 100644 --- a/kurl_proxy/assets/tls.html +++ b/kurl_proxy/assets/tls.html @@ -1,99 +1,212 @@ - - - - - - - Configure TLS | Admin Console - - {{if .AppIcon }} + + + + + + Configure TLS | Admin Console + + + {{if .AppIcon }} - {{end}} - - + {{end}} + + - -
-
-
-
-
- {{if .AppIcon }}{{end}} -
-

HTTPS for the {{ .AppTitle }} admin console

+ +
+ -
-

Certificate type

- - - - -
-

- A self-signed TLS certificate is currently used to secure communication - between your browser and the admin console. You will see a warning in your browser - every time you access the admin console unless you upload your own TLS certificate. -

- -
-

- Hostname - (optional) +

+
+
+ + Let's get you started! + +
+
+ check + Secure the Admin Console +
+
+ check + Configure the cluster (optional) +
+
+ check + Configure {{.AppTitle}} +
+
+ check + + Validate the environment & Install {{.AppTitle}} + +
+
+
+

Secure the Admin Console

+
+
+
+

+ HTTPS for the {{ .AppTitle }} admin console

-

-

Ensure this domain is routable on your network.

-
- - -
- - + diff --git a/kurl_proxy/assets/tls.js b/kurl_proxy/assets/tls.js index a2b2301986..455511abf0 100644 --- a/kurl_proxy/assets/tls.js +++ b/kurl_proxy/assets/tls.js @@ -9,15 +9,43 @@ function startTLS() { if (document.readyState !== "loading") { ready(); } else { - document.addEventListener('DOMContentLoaded', ready); + document.addEventListener("DOMContentLoaded", ready); } function ready() { selfSignedLabels = document.getElementsByClassName("self-signed-visible"); customCertLabels = document.getElementsByClassName("custom-cert-visible"); - function handleSubmit(e) { + document + .getElementById("self-signed") + .addEventListener("change", function () { + const certTypeBox = this.closest(".cert-type-box"); + const allCertBoxes = document.querySelectorAll(".cert-type-box"); + if (this.checked) { + allCertBoxes.forEach((box) => { + box.classList.remove("checked-background"); + if (box === certTypeBox) { + box.classList.add("checked-background"); + } + }); + } + }); + document + .getElementById("custom-cert") + .addEventListener("change", function () { + const certTypeBox = this.closest(".cert-type-box"); + const allCertBoxes = document.querySelectorAll(".cert-type-box"); + if (this.checked) { + allCertBoxes.forEach((box) => { + box.classList.remove("checked-background"); + if (box === certTypeBox) { + box.classList.add("checked-background"); + } + }); + } + }); + function handleSubmit(e) { if (useSelfSigned) { skipAndWait(e); return; @@ -36,10 +64,10 @@ function startTLS() { skip.addEventListener("click", skipAndWait); } - const typeToggle = document.getElementsByName('type'); + const typeToggle = document.getElementsByName("type"); typeToggle.forEach((el) => { - el.addEventListener('change', handleTypeToggle); + el.addEventListener("change", handleTypeToggle); }); keyInput = document.getElementById("key"); @@ -47,14 +75,14 @@ function startTLS() { keyInput.onchange = (e) => { keyLabel.innerHTML = e.target.files[0].name; - } + }; certInput = document.getElementById("cert"); certLabel = document.getElementById("cert-label"); certInput.onchange = (e) => { certLabel.innerHTML = e.target.files[0].name; - } + }; } function uploadAndWait(e) { @@ -69,11 +97,10 @@ function startTLS() { formData.append("hostname", hostnameInput.value); var xhr = new XMLHttpRequest(); - xhr.onerror = function () { showError(); enableForm(); - } + }; xhr.onloadend = function () { if (xhr.status === 200) { @@ -82,11 +109,11 @@ function startTLS() { } var resp = JSON.parse(xhr.response); - setErrorMsg(resp.error) + setErrorMsg(resp.error); showError(); enableForm(); - } + }; xhr.open("POST", "/tls"); xhr.send(formData); @@ -101,7 +128,7 @@ function startTLS() { var hostnameInput = document.getElementById("hostname"); var formData = new FormData(); - formData.append("hostname", hostnameInput.value) + formData.append("hostname", hostnameInput.value); var xhr = new XMLHttpRequest(); @@ -163,23 +190,27 @@ function startTLS() { } function hideError() { - document.getElementById("error").style.display = 'none'; + document.getElementById("error").style.display = "none"; } function showError() { - document.getElementById("error").style.display = ''; + document.getElementById("error").style.display = ""; } function disableForm() { - document.querySelectorAll("#upload-form input,#upload-form button").forEach(function (el) { - el.disabled = true; - }); + document + .querySelectorAll("#upload-form input,#upload-form button") + .forEach(function (el) { + el.disabled = true; + }); } function enableForm() { - document.querySelectorAll("#upload-form input,#upload-form button").forEach(function (el) { - el.disabled = false; - }); + document + .querySelectorAll("#upload-form input,#upload-form button") + .forEach(function (el) { + el.disabled = false; + }); } function toggleLabels() { @@ -194,10 +225,13 @@ function startTLS() { function handleTypeToggle(e) { if (e && e.target && e.target.value) { - if (e.target.value === "self-signed" || e.target.value === "custom-cert") { + if ( + e.target.value === "self-signed" || + e.target.value === "custom-cert" + ) { toggleLabels(); } } } -}; +} startTLS(); diff --git a/kurl_proxy/assets/welcome.html b/kurl_proxy/assets/welcome.html new file mode 100644 index 0000000000..1a1cf5c63d --- /dev/null +++ b/kurl_proxy/assets/welcome.html @@ -0,0 +1,99 @@ + + + + + + + + Welcome to {{.AppTitle}} Admin Console + + + {{if .AppIcon }} + + {{end}} + + + +
+
+
+ {{if .AppIcon }}{{end}} +
+

{{ .AppTitle }} Admin Console

+
+
+
+
+ {{if .AppIcon }}{{end}} +
+ +

+ Welcome to the {{ .AppTitle }} Admin Console +

+ +

+ You will be guided through the setup and installation of + {{.AppTitle}} +

+

Let's get you started!

+
+
+
+ check +

Secure the Admin Console

+
+
+ check +

+ Configure the cluster (optional) +

+
+
+ check +

Configure {{.AppTitle}}

+
+
+ check +

+ Validate the environment & Install {{.AppTitle}} +

+
+
+ +
+ +
+
+
+
+ + diff --git a/kurl_proxy/cmd/main.go b/kurl_proxy/cmd/main.go index 79aa905054..0e50585bd7 100644 --- a/kurl_proxy/cmd/main.go +++ b/kurl_proxy/cmd/main.go @@ -270,6 +270,32 @@ func getHttpServer(fingerprint string, acceptAnonymousUploads bool, assetsDir st app, err := kotsadmApplication() + if err != nil { + log.Printf("No kotsadm application metadata: %v", err) // continue + } + appIcon := template.URL(app.Spec.Icon) + c.HTML(http.StatusOK, "welcome.html", gin.H{ + "fingerprintSHA1": fingerprint, + "AppIcon": appIcon, + "AppTitle": app.Spec.Title, + }) + }) + r.GET("/insecure", func(c *gin.Context) { + if !acceptAnonymousUploads { + log.Println("TLS certs already uploaded, redirecting to https") + target := url.URL{ + Scheme: "https", + Host: c.Request.Host, + Path: c.Request.URL.Path, + RawQuery: c.Request.URL.RawQuery, + } + // Returns StatusFound (302) to avoid browser caching + c.Redirect(http.StatusFound, target.String()) + return + } + + app, err := kotsadmApplication() + if err != nil { log.Printf("No kotsadm application metadata: %v", err) // continue } diff --git a/web/src/Root.tsx b/web/src/Root.tsx index e2c5048ab1..ab6688200a 100644 --- a/web/src/Root.tsx +++ b/web/src/Root.tsx @@ -1,4 +1,4 @@ -import { createContext, useEffect, useReducer } from "react"; +import { createContext, useEffect, useReducer, useState } from "react"; import { createBrowserHistory } from "history"; import { Navigate, Route, Routes, useNavigate } from "react-router-dom"; import { Helmet } from "react-helmet"; @@ -56,6 +56,9 @@ import AppSnapshotRestore from "@components/snapshots/AppSnapshotRestore"; import EmbeddedClusterViewNode from "@components/apps/EmbeddedClusterViewNode"; import UpgradeStatusModal from "@components/modals/UpgradeStatusModal"; import AppLoading from "@components/apps/AppLoading"; +import Icon from "@components/Icon"; + +import "./scss/components/watches/WatchConfig.scss"; // react-query client const queryClient = new QueryClient(); @@ -103,6 +106,7 @@ type State = { snapshotInProgressApps: string[]; isEmbeddedClusterWaitingForNodes: boolean; themeState: ThemeState; + activeGroups: string[]; }; let interval: ReturnType | undefined; @@ -120,6 +124,7 @@ const Root = () => { appSlugFromMetadata: null, appNameSpace: null, adminConsoleMetadata: null, + activeGroups: null, connectionTerminated: false, showUpgradeStatusModal: false, upgradeStatus: "", @@ -450,6 +455,46 @@ const Root = () => { }; const navigate = useNavigate(); + const [currentStep, setCurrentStep] = useState(0); + const [navbarConfigGroups, setNavbarConfigGroups] = useState([]); + const [activeGroups, setActiveGroups] = useState([]); + + const getStepProps = (step: number) => { + if (step < currentStep) { + return { + icon: "check-circle-filled", + textColor: "tw-text-gray-400", + fontClass: "", + }; + } else if (step === currentStep) { + return { + icon: "check-gray-filled", + textColor: "tw-text-gray-800", + fontClass: "tw-font-bold", + }; + } else { + return { + icon: "check-gray-filled", + textColor: "", + fontClass: "", + }; + } + }; + + const toggleActiveGroups = (name: string) => { + let groupsArr = activeGroups; + console.log(groupsArr, "arr"); + if (groupsArr.includes(name)) { + let updatedGroupsArr = groupsArr.filter((n) => n !== name); + console.log("ncludes", updatedGroupsArr); + setActiveGroups(updatedGroupsArr); + } else { + groupsArr.push(name); + console.log("add to it ", groupsArr); + setActiveGroups(groupsArr); + } + }; + return ( @@ -493,6 +538,7 @@ const Root = () => { {/* eslint-disable-next-line */} {/* @ts-ignore */} + { isEmbeddedClusterEnabled={Boolean( state.adminConsoleMetadata?.isEmbeddedCluster )} - isEmbeddedClusterWaitingForNodes={ - state.isEmbeddedClusterWaitingForNodes - } isGitOpsSupported={isGitOpsSupported()} isIdentityServiceSupported={isIdentityServiceSupported()} appsList={state.appsList} @@ -511,431 +554,604 @@ const Root = () => { isSnapshotsSupported={isSnapshotsSupported()} errLoggingOut={state.errLoggingOut} /> -
- - - } - /> - } />{" "} - } /> - - } - /> - - } - /> - - } - /> - + {Utilities.isInitialAppInstall(state.appsList[0]) && + Utilities.isLoggedIn() && ( +
+
+ + Let's get you started! + +
+
+ + + Secure the Admin Console + +
+
+ + + Configure the cluster (optional) + +
+
+
+ + + Configure {state.selectedAppName || ""} + +
+ {navbarConfigGroups.length > 0 && ( +
+ {navbarConfigGroups?.map((group, i) => { + if ( + group.title === "" || + group.title.length === 0 || + group.hidden || + group.when === "false" + ) { + return; + } + return ( +
+
toggleActiveGroups(group.name)} + > +
+ {group.title} +
+ {/* adding the arrow-down classes, will rotate the icon when clicked */} + +
+ {group.items ? ( +
+ {group.items + ?.filter((item) => item.type !== "label") + ?.map((item, j) => { + const hash = location.hash.slice(1); + if ( + item.hidden || + item.when === "false" + ) { + return; + } + return ( + + {item.title} + + ); + })} +
+ ) : null} +
+ ); + })} +
)} - /> - } - /> - } /> - } /> - - } - /> - - } - /> - - } - /> - } /> - {state.adminConsoleMetadata?.isEmbeddedCluster && ( - <> - - } - /> - } - /> - +
+
+ + + Validate the environment & Install{" "} + {state.selectedAppName || ""} + +
+
)} - {(state.adminConsoleMetadata?.isKurl || - state.adminConsoleMetadata?.isEmbeddedCluster) && ( + +
+ - ) : ( - - ) + } /> - )} - {state.adminConsoleMetadata?.isEmbeddedCluster && ( + } />{" "} + } /> } - /> - )} - } - /> - - } - /> - {/* :tab? */} - - } - > - } /> } /> } /> - } /> } /> + } /> + } + /> } /> } - /> - - - } - /> - - } - > - } /> } /> - - } - /> + } /> + {state.adminConsoleMetadata?.isEmbeddedCluster && ( + <> + + } + /> + } + /> + + )} + {(state.adminConsoleMetadata?.isKurl || + state.adminConsoleMetadata?.isEmbeddedCluster) && ( + + ) : ( + + ) + } + /> + )} + {state.adminConsoleMetadata?.isEmbeddedCluster && ( + } + /> + )} } + path="/gitops" + element={} /> } /> + {/* :tab? */} } - /> - - } > } /> } /> } - > - } /> - } /> - } - /> - - } /> - } /> + path="details/:id" + element={ + + } + /> } + path=":slug/:id/restore" + element={} + /> + + } + /> + + } + /> + } /> - } /> } /> } - /> - {/* WHERE IS SELECTEDAPP */} - {state.app?.isAppIdentityServiceSupported && ( + path="/app/*" + element={ + + } + > } + path=":slug" + element={ + + } /> - )} - {/* snapshots redirects */} - } - /> - } - /> - } - /> + + } + /> + + } + /> + } + /> + + } + /> + + } + /> + + } + > + + } + /> + + } + /> + } + > + } /> + } + /> + } + /> + + } /> + } /> + } + /> + } /> + + + } + /> + } + /> + {/* WHERE IS SELECTEDAPP */} + {state.app?.isAppIdentityServiceSupported && ( + } + /> + )} + {/* snapshots redirects */} + } + /> + } + /> + } + /> + + } + /> + + } /> + + } /> - - } /> - - - } - /> - + +