diff --git a/website/source/assets/images/icon-checkmark-circle.svg b/website/source/assets/images/icon-checkmark-circle.svg new file mode 100644 index 0000000000..8a7549f327 --- /dev/null +++ b/website/source/assets/images/icon-checkmark-circle.svg @@ -0,0 +1,6 @@ + + diff --git a/website/source/assets/images/icon-warning.svg b/website/source/assets/images/icon-warning.svg new file mode 100644 index 0000000000..82b1265576 --- /dev/null +++ b/website/source/assets/images/icon-warning.svg @@ -0,0 +1,4 @@ + + diff --git a/website/source/assets/javascripts/application.js b/website/source/assets/javascripts/application.js index 51c8914f8f..646543796a 100644 --- a/website/source/assets/javascripts/application.js +++ b/website/source/assets/javascripts/application.js @@ -1,8 +1,13 @@ //= require turbolinks //= require jquery +//= require lib/file-saver.min //= require hashicorp/mega-nav //= require hashicorp/sidebar //= require hashicorp/analytics //= require analytics +//= require tabs +//= require os-detect +//= require downloads +//= require configuration-builder diff --git a/website/source/assets/javascripts/configuration-builder.js b/website/source/assets/javascripts/configuration-builder.js new file mode 100644 index 0000000000..21db9d3158 --- /dev/null +++ b/website/source/assets/javascripts/configuration-builder.js @@ -0,0 +1,133 @@ +function downloadConfiguration() { + var form = document.querySelector("#configuration-builder"); + var config = ""; + + // Add Listener stanza + if (document.getElementById("include_tcp_listener").checked) { + config += `listener "tcp" { +${addFieldsToStanza("listener")}} +`; + } + + // Add Storage stanza + if (document.getElementById("include_storage").checked) { + var backend = document.getElementById("storage").value; + config += ` +storage "${backend}" { +${addFieldsToStanza("storage")}} +`; + } + + // Add Telemetry stanza + if (document.getElementById("include_telemetry").checked) { + var provider = document.getElementById("telemetry").value; + config += ` +telemetry { +${addFieldsToStanza("telemetry")}} +`; + } + + // Add Seal stanza + if (document.getElementById("include_seal").checked) { + var type = document.getElementById("seal").value; + config += ` +seal "${type}" { +${addFieldsToStanza("seal")}} +`; + } + + // Add UI stanza + if (document.getElementById("include_ui").checked) { + config += ` +ui = true`; + var startServerLink = document.querySelector(".start-server-link") + startServerLink.href = `${startServerLink.href}?tab=ui`; + } + + config = config.replace(/([^\r])\n/g, "$1\r\n"); + var blob = new Blob([config], {type: "text/plain;charset=utf-8"}); + saveAs(blob, "vault-config.hcl"); + document.querySelector(".form-actions").style.display = "none"; + document.querySelector("#download-confirm").style.display = "block"; + return false; +} + +function addFieldsToStanza(stanza) { + var fieldsets = document.querySelectorAll(`[data-config-stanza="${stanza}"] .nested-fields fieldset`); + var lines = ""; + + for (i = 0; i < fieldsets.length; i++) { + var fieldset = fieldsets[i]; + if (fieldset.offsetWidth > 0 && fieldset.offsetHeight > 0) { + var line = fieldsetToLine(fieldset); + if (line) { + lines += line; + } + } + } + return lines; +} + +function fieldsetToLine(fieldset) { + var parameter = fieldset.getAttribute("name"); + var isChecked = document.querySelector(`#include_${parameter}`).checked; + if (isChecked) { + var field = fieldset.querySelector(`#${parameter}`); + var value = field.value; + + if (field.getAttribute("type") == "number") { + return ` ${parameter} = ${value} +`; + } else { + return ` ${parameter} = "${value}" +`; + } + } + return; +} + +document.addEventListener("turbolinks:load", function() { + var revealTriggers = document.querySelectorAll(".reveal-trigger"); + var configTriggers = document.querySelectorAll(".config-reveal-trigger"); + var configSelects = document.querySelectorAll(".config-reveal-select"); + + for (i = 0; i < revealTriggers.length; i++) { + revealTriggers[i].addEventListener("click", function(clickEvent) { + var revealTrigger = clickEvent.currentTarget; + revealTrigger.classList.toggle("active"); + revealTrigger.nextElementSibling.classList.toggle("active"); + }); + } + + for (i = 0; i < configTriggers.length; i++) { + configTriggers[i].addEventListener("change", function(clickEvent) { + var configTrigger = clickEvent.currentTarget; + var container = configTrigger.closest("fieldset"); + var reveal = container.querySelector(".config-reveal-container"); + reveal.classList.toggle("active"); + + if (reveal.querySelector(".config-reveal-select")) { + var selection = reveal.querySelector(".config-reveal-select").value; + document.querySelector(`[data-if-option="${selection}"]`).classList.toggle("active"); + } + }); + } + + for (i = 0; i < configSelects.length; i++) { + configSelects[i].addEventListener("change", function(clickEvent) { + var configSelect = clickEvent.currentTarget; + var selection = configSelect.value; + var section = configSelect.closest("section"); + var reveal = section.querySelector(`[data-if-option='${selection}']`); + var nestedOptions = section.querySelectorAll("[data-if-option]"); + + for (i = 0; i < nestedOptions.length; i++) { + nestedOptions[i].classList.remove("active"); + } + + if (reveal) { + reveal.classList.add("active"); + } + }); + } +}); diff --git a/website/source/assets/javascripts/downloads.js b/website/source/assets/javascripts/downloads.js new file mode 100644 index 0000000000..1f4226faa1 --- /dev/null +++ b/website/source/assets/javascripts/downloads.js @@ -0,0 +1,22 @@ +document.addEventListener("turbolinks:load", function() { + var downloadLinks = document.querySelectorAll(".download-arches .download-link"); + + for (i = 0; i < downloadLinks.length; i++) { + downloadLinks[i].addEventListener("click", handleDownloadLinkClick); + } + + function handleDownloadLinkClick(clickEvent) { + var clickedLink = clickEvent.currentTarget; + var bit = clickedLink.innerHTML; + var container = clickedLink.closest(".download"); + var name = container.querySelector(".os-name").innerHTML; + var icon = container.querySelector(".icon svg").outerHTML; + var confirm = document.querySelector("#download-confirm"); + + document.querySelector(".download-arches").style.display = "none"; + confirm.style.display = "flex"; + confirm.querySelector(".chosen-os-name").innerHTML = name; + confirm.querySelector(".chosen-os-bit").innerHTML = bit; + confirm.querySelector(".icon").innerHTML = icon; + } +}); diff --git a/website/source/assets/javascripts/lib/file-saver.min.js b/website/source/assets/javascripts/lib/file-saver.min.js new file mode 100644 index 0000000000..9a1e397f20 --- /dev/null +++ b/website/source/assets/javascripts/lib/file-saver.min.js @@ -0,0 +1,2 @@ +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})} diff --git a/website/source/assets/javascripts/os-detect.js b/website/source/assets/javascripts/os-detect.js new file mode 100644 index 0000000000..d33b4d31cf --- /dev/null +++ b/website/source/assets/javascripts/os-detect.js @@ -0,0 +1,31 @@ +function getCurrentOS() { + var userAgent = navigator.userAgent; + if (userAgent.indexOf("Win") != -1) return "windows"; + if (userAgent.indexOf("Mac") != -1) return "darwin"; + if (userAgent.indexOf("Linux") != -1) return "linux"; + if (userAgent.indexOf("NetBSD") != -1) return "netbsd"; + if (userAgent.indexOf("FreeBSD") != -1) return "freebsd"; + if (userAgent.indexOf("OpenBSD") != -1) return "openbsd"; + if (userAgent.indexOf("SunOS") != -1) return "solaris"; + return "Unkown"; +} + +function getCurrentOSBit() { + var userAgent = navigator.userAgent; + if (userAgent.match( /(Win64|WOW64|Mac OS X 10|amd64|x86)/ )) { + return "64-bit"; + } + if (userAgent.match( /arm/ )) { + return "arm"; + } + return "32-bit"; +} + +document.addEventListener("turbolinks:load", function() { + if (document.querySelector(`[data-os]`)) { + var currentOSElement = document.querySelector(`[data-os="${getCurrentOS()}"]`); + var currentBitLinkElement = document.querySelector(`[data-os="${getCurrentOS()}"] [data-os-bit="${getCurrentOSBit()}"]`); + currentOSElement.classList.add("current"); + currentBitLinkElement.classList.add("current"); + } +}); diff --git a/website/source/assets/javascripts/tabs.js b/website/source/assets/javascripts/tabs.js new file mode 100644 index 0000000000..b2972c15af --- /dev/null +++ b/website/source/assets/javascripts/tabs.js @@ -0,0 +1,40 @@ +document.addEventListener("turbolinks:load", function() { + var tabs = document.querySelectorAll(".tabs li"); + + function handleTabClick(clickEvent) { + var clickedLink = clickEvent.currentTarget.querySelector("a"); + var activeContentId = clickedLink.getAttribute("data-tab-for"); + + switchTab(activeContentId); + + clickEvent.preventDefault(activeContentId); + return false; + } + + function switchTab(id) { + var tabsContent = document.querySelectorAll(".tabs-content"); + var activeTab = document.querySelector(`[data-tab-for="${id}"]`); + var activeContent = document.getElementById(id); + + for (var i = 0; i < tabs.length; i++) { + var tabLink = tabs[i].querySelector("a"); + tabLink.classList.remove("is-active"); + } + + for (i = 0; i < tabsContent.length; i++) { + tabsContent[i].classList.remove("is-active"); + } + + activeTab.classList.add("is-active"); + activeContent.classList.add("is-active"); + } + + for (i = 0; i < tabs.length; i++) { + tabs[i].addEventListener("click", handleTabClick) + } + + var urlParams = new URLSearchParams(window.location.search); + if (urlParams && urlParams.has("tab")) { + switchTab(urlParams.get("tab")); + } +}); diff --git a/website/source/assets/stylesheets/_config.scss b/website/source/assets/stylesheets/_config.scss new file mode 100644 index 0000000000..841f07b718 --- /dev/null +++ b/website/source/assets/stylesheets/_config.scss @@ -0,0 +1,64 @@ +.config-reveal-label { + .config-reveal-trigger:not(:checked) + & { + color: #aaa; + } + + .docs-info-icon { + &::before { + content: '\0024D8'; + color: #AAA; + display: inline-block; + height: 1em; + margin-left: 0.25em; + width: 1em; + } + + &:hover::before { + color: inherit; + } + } +} + +.reveal-container, +.config-reveal-container { + display: none; + margin-left: 20px; + + &.active { + display: block; + } +} + +.reveal-trigger { + align-items: center; + color: $sidebar-link-color-active; + cursor: pointer; + display: flex; + font-size: $sidebar-font-size; + margin: -5px 0 10px; + + &::before { + content: '\203A'; + display: inline-block; + height: 1em; + line-height: 1; + text-align: center; + transform: rotate(90deg); + width: 1em; + } + + &::after { + content: attr(data-show-text); + margin-left: 0.5em; + } + + &.active { + &::before { + transform: rotate(-90deg); + } + + &::after { + content: attr(data-hide-text); + } + } +} diff --git a/website/source/assets/stylesheets/_downloads.scss b/website/source/assets/stylesheets/_downloads.scss index 97a4dfc66b..9bc53e55e7 100644 --- a/website/source/assets/stylesheets/_downloads.scss +++ b/website/source/assets/stylesheets/_downloads.scss @@ -1,16 +1,15 @@ body.layout-downloads { #inner { .downloads { - margin-top: 20px; - .description { margin-bottom: 20px; } .download { - align-items: center; - border-bottom: 1px solid #b2b2b2; + border: 1px solid #ddd; + border-radius: 8px; display: flex; + margin: 6px 0; padding: 15px; .details { @@ -51,10 +50,75 @@ body.layout-downloads { } } - .poweredby { - margin-top: 20px; - text-align: center; + .download-arches { + @media (min-width: 992px) { + display: flex; + flex-wrap: wrap; + } + + .download { + @media (min-width: 992px) { + margin: 6px; + order: 1; + width: calc(50% - 12px); + } + + &.current { + border: 1px solid #909FA8; + order: 0; + width: 100%; + + .current { + .download-link { + @extend .button; + @extend .primary; + line-height: 1; + order: 0; + padding: 10px 15px; + + &::before { + content: "Download " + } + + &:hover { + text-decoration: none; + } + } + } + } + } } } } + + .poweredby { + float: right; + margin-top: 10px; + text-align: center; + } +} + +#download-confirm, +body.layout-downloads .downloads #download-confirm.download { + border: 1px solid #2EB039; + border-radius: 8px; + box-shadow: 0 4px 4px rgba($black, 0.09), 0 4px 12px rgba($black, 0.05); + display: none; + padding: 15px; + + .details { + padding-left: 20px; + + h2 { + margin: 4px 0 0; + border: none; + } + } + + .download-confirm-message { + background: url("/assets/images/icon-checkmark-circle.svg") left center no-repeat; + color: #2EB039; + margin-bottom: 20px; + padding-left: 2rem; + } } diff --git a/website/source/assets/stylesheets/_forms.scss b/website/source/assets/stylesheets/_forms.scss new file mode 100644 index 0000000000..bbef082767 --- /dev/null +++ b/website/source/assets/stylesheets/_forms.scss @@ -0,0 +1,156 @@ +label { + cursor: pointer; +} + +.label { + color: $gray-darker; + display: block; + font-size: 13px; + margin-bottom: 2px; + text-align: left; +} + +fieldset { + margin-bottom: 10px; +} + +.checkbox-label { + padding-left: 0; + + input[type="checkbox"] { + margin-right: 5px; + } + + & + .input, + & + .textarea, + & + .select { + margin-left: 20px; + max-width: calc(100% - 20px); + } +} + +.input, +.textarea, +.select select { + appearance: none; + -webkit-appearance: none; + align-items: center; + background-color: #fff; + border-radius: 2px; + border: 1px solid #BAC1CC; + color: #000; + display: block; + height: 36px; + justify-content: flex-start; + line-height: 1.5; + padding: calc(.375em - 1px) 12px; + vertical-align: top; + max-width: 100%; + width: 100%; + + &::placeholder { + opacity: 0.5; + } +} + +.input, +.textarea, +.select { + display: block; + height: 36px; + margin-bottom: 10px; + max-width: 100%; + position: relative; + width: 100%; +} + +.input[disabled], +.textarea[disabled] { + border-color: #E1E5EB; + background-color: #FAFAFA; + box-shadow: none; + color: #8e96a3; +} + + +.input, +.textarea { + box-shadow: 0 4px 1px rgba($black, 0.06) inset; + + &:focus, + &.is-focused, + &:active, + &.is-active { + border-color: #0068FF; + } +} + +.select select { + background-color: #F7F8FA; + box-shadow: 0 3px 1px rgba($black, 0.12); + + .has-background-grey-lighter & { + background-color: $white; + } +} + +.select::after { + border: 1px solid $black; + border-right: 0; + border-top: 0; + border-width: 2px; + content: " "; + display: block; + height: 7px; + margin-top: 0; + pointer-events: none; + position: absolute; + right: 1.125em; + top: 50%; + transform: translateY(20%) rotate(-45deg); + width: 7px; + z-index: 4; +} + +.select::before { + @extend .select::after; + transform: translateY(-75%) rotate(135deg); + z-index: 5; +} + +.nested-fields { + border: 1px solid #E1E5EB; + border-radius: 4px; + margin: 0 0 20px 20px; + padding: 10px 20px 0; +} + +.form-hint { + color: #aaa; + font-size: 1.2rem; + font-weight: bold; + margin: -5px 12px 10px; +} + +.form-input-warning { + color: #614903; + + &::before { + background: url("/assets/images/icon-warning.svg") left center no-repeat; + content: ""; + display: inline-block; + height: 12px; + margin-right: 0.25rem; + width: 12px; + vertical-align: -0.1rem; + } +} + +.form-actions { + margin-top: 30px; + + .button { + line-height: 1; + padding: 11px 15px 8px 15px; + } +} diff --git a/website/source/assets/stylesheets/_home.scss b/website/source/assets/stylesheets/_home.scss index 823719fdbe..770b02383f 100755 --- a/website/source/assets/stylesheets/_home.scss +++ b/website/source/assets/stylesheets/_home.scss @@ -61,6 +61,25 @@ text-align: center; z-index: 1; + .get-started-links { + p { + margin-top: 0; + text-align: center; + } + + a { + margin: 0 0.5em; + } + + a:not(.button) { + border-bottom: 1px dashed #00ABE0; + color: #000; + font-size: 16px; + font-weight: 500; + text-decoration: none; + } + } + #tag-line { display: block; font-size: 24px; diff --git a/website/source/assets/stylesheets/_tabs.scss b/website/source/assets/stylesheets/_tabs.scss new file mode 100644 index 0000000000..1ec3495a25 --- /dev/null +++ b/website/source/assets/stylesheets/_tabs.scss @@ -0,0 +1,60 @@ +#inner .tabs { + user-select: none; + align-items: stretch; + display: flex; + font-size: 1rem; + justify-content: space-between; + margin-bottom: 1em; + overflow: hidden; + overflow-x: auto; + white-space: nowrap; + + p { + display: none; + } + + ul { + align-items: center; + border-bottom-color: #BAC1CC; + border-bottom-style: solid; + border-bottom-width: 1px; + display: flex; + flex-grow: 1; + flex-shrink: 0; + list-style: none; + justify-content: flex-start; + padding: 0; + } + + li { + margin: 0; + padding: 0 1rem; + } + + a { + align-items: center; + display: flex; + justify-content: center; + margin-bottom: -1px; + vertical-align: top; + color: #525761; + font-weight: 600; + text-decoration: none; + padding: 1rem 0.5rem 0.5rem; + border-bottom: 2px solid transparent; + transition: border-color 150ms; + + &.is-active { + border-color: #00ABE0; + color: #00ABE0; + } + } +} + +.tabs-content { + display: none; + + &.is-active { + display: block; + } +} diff --git a/website/source/assets/stylesheets/application.scss b/website/source/assets/stylesheets/application.scss index 3af5a28777..a451421578 100755 --- a/website/source/assets/stylesheets/application.scss +++ b/website/source/assets/stylesheets/application.scss @@ -25,6 +25,8 @@ @import '_buttons'; @import '_syntax'; @import '_logos'; +@import '_forms'; +@import '_tabs'; // Pages @import '_community'; @@ -32,6 +34,7 @@ @import '_downloads'; @import '_home'; @import '_latest'; +@import '_config'; // Demo @import '_demo'; diff --git a/website/source/docs/configuration/builder.html.erb b/website/source/docs/configuration/builder.html.erb new file mode 100644 index 0000000000..7b19be53cb --- /dev/null +++ b/website/source/docs/configuration/builder.html.erb @@ -0,0 +1,70 @@ +--- +layout: "docs" +page_title: "Server Configuration" +sidebar_current: "docs-configuration" +description: |- + Vault server configuration reference. +--- + +
+ Choose from the options below (some are required) and download your + configuration file. Some variables may be sensitive, so we will give you + placeholders that you can replace after downloading. +
+ + diff --git a/website/source/docs/configuration/builder/_reveal_label.html.erb b/website/source/docs/configuration/builder/_reveal_label.html.erb new file mode 100644 index 0000000000..018eea5ef3 --- /dev/null +++ b/website/source/docs/configuration/builder/_reveal_label.html.erb @@ -0,0 +1,16 @@ + diff --git a/website/source/docs/configuration/builder/_reveal_number_field.html.erb b/website/source/docs/configuration/builder/_reveal_number_field.html.erb new file mode 100644 index 0000000000..3ef2414db7 --- /dev/null +++ b/website/source/docs/configuration/builder/_reveal_number_field.html.erb @@ -0,0 +1,21 @@ + diff --git a/website/source/docs/configuration/builder/_reveal_select_field.html.erb b/website/source/docs/configuration/builder/_reveal_select_field.html.erb new file mode 100644 index 0000000000..29aa564ff7 --- /dev/null +++ b/website/source/docs/configuration/builder/_reveal_select_field.html.erb @@ -0,0 +1,22 @@ + diff --git a/website/source/docs/configuration/builder/_reveal_text_field.html.erb b/website/source/docs/configuration/builder/_reveal_text_field.html.erb new file mode 100644 index 0000000000..2449b7e1b4 --- /dev/null +++ b/website/source/docs/configuration/builder/_reveal_text_field.html.erb @@ -0,0 +1,26 @@ + diff --git a/website/source/docs/configuration/builder/_section_listener.html.erb b/website/source/docs/configuration/builder/_section_listener.html.erb new file mode 100644 index 0000000000..4abf9020ea --- /dev/null +++ b/website/source/docs/configuration/builder/_section_listener.html.erb @@ -0,0 +1,156 @@ +Below are the available downloads for the latest version of Vault (<%= latest_version %>). Please download the proper package for your - operating system and architecture. + operating system and architecture. Check out the + + v<%= latest_version %> CHANGELOG + + for information on the latest release.
+You can find the @@ -26,36 +78,21 @@ description: |- verify the checksums signature file which has been signed using HashiCorp's GPG key. - You can also download older versions of Vault from the releases service.
-Check out the v<%= latest_version %> CHANGELOG for information on the latest release.
-Community resources are available to learn more about Vault and interact with the community.
You can download older versions of Vault from the releases service.
Community resources are available to learn more about Vault and interact with the community.