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

UI - ent init #5428

Merged
merged 9 commits into from Sep 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 16 additions & 2 deletions ui/app/controllers/vault/cluster/init.js
Expand Up @@ -40,15 +40,29 @@ export default Controller.extend(DEFAULTS, {

actions: {
initCluster(data) {
let isCloudSeal = !!this.model.sealType && this.model.sealType !== 'shamir';
if (data.secret_shares) {
data.secret_shares = parseInt(data.secret_shares);
let shares = parseInt(data.secret_shares, 10);
data.secret_shares = shares;
if (isCloudSeal) {
data.stored_shares = 1;
data.recovery_shares = shares;
}
}
if (data.secret_threshold) {
data.secret_threshold = parseInt(data.secret_threshold);
let threshold = parseInt(data.secret_threshold, 10);
data.secret_threshold = threshold;
if (isCloudSeal) {
data.recovery_threshold = threshold;
}
}
if (!data.use_pgp) {
delete data.pgp_keys;
}
if (data.use_pgp && isCloudSeal) {
data.recovery_pgp_keys = data.pgp_keys;
}

if (!data.use_pgp_for_root) {
delete data.root_token_pgp_key;
}
Expand Down
5 changes: 4 additions & 1 deletion ui/app/machines/tutorial-machine.js
Expand Up @@ -34,7 +34,10 @@ export default {
onEntry: { type: 'render', level: 'feature', component: 'wizard/init-setup' },
},
save: {
on: { TOUNSEAL: 'unseal' },
on: {
TOUNSEAL: 'unseal',

Choose a reason for hiding this comment

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

These look slightly weird, like they should have an _ in them, is this due to some sort of restriction, or just then way you've gone? (wheres a 🦭 🌊 emoji when you need one 😂)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yeah this was more keeping in line with what's there already - I'll make a note to add underscores later as we've got more work to do on the on boarding stuff.

TOLOGIN: 'login',
},
onEntry: { type: 'render', level: 'feature', component: 'wizard/init-save-keys' },
},
unseal: {
Expand Down
6 changes: 2 additions & 4 deletions ui/app/models/cluster.js
Expand Up @@ -12,16 +12,13 @@ export default DS.Model.extend({
name: attr('string'),
status: attr('string'),
standby: attr('boolean'),
type: attr('string'),

needsInit: computed('nodes', 'nodes.[]', function() {
// needs init if no nodes are initialized
return this.get('nodes').isEvery('initialized', false);
}),

type: computed(function() {
return this.constructor.modelName;
}),

unsealed: computed('nodes', 'nodes.{[],@each.sealed}', function() {
// unsealed if there's at least one unsealed node
return !!this.get('nodes').findBy('sealed', false);
Expand All @@ -40,6 +37,7 @@ export default DS.Model.extend({

sealThreshold: alias('leaderNode.sealThreshold'),
sealProgress: alias('leaderNode.progress'),
sealType: alias('leaderNode.type'),
hasProgress: gte('sealProgress', 1),

//replication mode - will only ever be 'unsupported'
Expand Down
6 changes: 1 addition & 5 deletions ui/app/models/node.js
@@ -1,4 +1,3 @@
import { computed } from '@ember/object';
import { alias, and, equal } from '@ember/object/computed';
import DS from 'ember-data';
const { attr } = DS;

Choose a reason for hiding this comment

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

Unrelated, but you ought to be able to use modules for Ember Data as well now.

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh I guess the codemod doesn't do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oddly the guides still show the old way - gonna hold off on this now and do it all at once in a different PR.

Expand All @@ -24,13 +23,10 @@ export default DS.Model.extend({
sealThreshold: alias('t'),
sealNumShares: alias('n'),
version: attr('string'),
type: attr('string'),

//https://www.vaultproject.io/docs/http/sys-leader.html
haEnabled: attr('boolean'),
isSelf: attr('boolean'),
leaderAddress: attr('string'),

type: computed(function() {
return this.constructor.modelName;
}),
});
140 changes: 102 additions & 38 deletions ui/app/templates/vault/cluster/init.hbs
@@ -1,33 +1,56 @@
<SplashPage as |Page|>
{{#if keyData}}
<Page.header>
<h1 class="title is-4">
Vault has been initialized! {{#if (eq keyData.keys.length 1)}}
Here is your key.
{{else}}
Here are your {{pluralize keyData.keys.length "key"}}.
{{/if}}
</h1>
{{#let (or keyData.recovery_keys keyData.keys) as |keyArray|}}
<h1 class="title is-4">
Vault has been initialized!
{{#if (eq keyArray.length 1)}}
Here is your key.
{{else}}
Here are your {{pluralize keyArray.length "key"}}.
{{/if}}
</h1>
{{/let}}
</Page.header>
<Page.content>
<div class="box is-marginless is-shadowless">
<div class="content">
<p>
Please securely distribute the keys below. When the Vault is re-sealed, restarted, or stopped, you must provide at least <strong class="has-text-danger">{{secret_threshold}}</strong> of these keys to unseal it again.
Vault does not store the master key. Without at least <strong class="has-text-danger">{{secret_threshold}}</strong> keys, your Vault will remain permanently sealed.
{{#if keyData.recovery_keys}}
Please securely distribute the keys below. Certain privileged operations in Vault such as rekeying the
barrier or generating a new root token will require you to provide
at least <strong class="has-text-danger">{{secret_threshold}}</strong> of these keys to perform the
operation.
{{else}}
Please securely distribute the keys below. When the Vault is re-sealed, restarted, or stopped, you must
provide at least <strong class="has-text-danger">{{secret_threshold}}</strong> of these keys to unseal it
again.
Vault does not store the master key. Without at least <strong class="has-text-danger">{{secret_threshold}}</strong>
keys, your Vault will remain permanently sealed.
{{/if}}
</p>
</div>
<div class="message is-list is-highlight has-copy-button" tabindex="-1">
<HoverCopyButton @alwaysShow=true @copyValue={{keyData.root_token}} />
<div
class="message is-list is-highlight has-copy-button"
tabindex="-1"
>
<HoverCopyButton
@alwaysShow=true
@copyValue={{keyData.root_token}}
/>
<div class="message-body">
<h4 class="title is-7 is-marginless">
Initial Root Token
</h4>
<code class="is-word-break">{{keyData.root_token}}</code>
</div>
</div>
{{#each (if keyData.keys_base64 keyData.keys_base64 keyData.keys) as |key index| }}
<div class="message is-list has-copy-button" tabindex="-1">
{{#each (or keyData.recovery_keys_base64 keyData.recovery_keys keyData.keys_base64 keyData.keys) as |key index|}}
<div
data-test-key-box
class="message is-list has-copy-button"
tabindex="-1"
>
<HoverCopyButton @copyValue={{key}} />
<div class="message-body">
<h4 class="title is-7 is-marginless">
Expand All @@ -40,16 +63,26 @@
</div>
<div class="box is-marginless is-shadowless">
<div class="field is-grouped-split">
{{#if model.sealed}}
<div class="control">
{{#if (and model.sealed (not keyData.recovery_keys))}}
<div
data-test-advance-button
class="control"
>
{{#link-to 'vault.cluster.unseal' model.name class="button is-primary"}}
Continue to Unseal
Continue to Unseal
{{/link-to}}
</div>
{{else}}
<div class="control">
{{#link-to 'vault.cluster.auth' model.name class="button is-primary"}}
Continue to Authenticate
<div
data-test-advance-button
class="control"
>
{{#link-to 'vault.cluster.auth'
model.name
class=(concat (if model.sealed 'is-loading ' '') 'button is-primary')
disabled=model.sealed
}}
Continue to Authenticate
{{/link-to}}
</div>
{{/if}}
Expand All @@ -60,7 +93,7 @@
@extension="json"
@class="button is-ghost"
@stringify={{true}}
>
>
<ICon @glyph="download" @size=16 /> Download Keys
</DownloadButton>
</div>
Expand All @@ -73,56 +106,84 @@
</h1>
</Page.header>
<Page.content>
<form {{action 'initCluster' (hash
secret_shares=secret_shares
secret_threshold=secret_threshold
pgp_keys=pgp_keys
use_pgp=use_pgp
use_pgp_for_root=use_pgp_for_root
root_token_pgp_key=root_token_pgp_key
<form
{{action 'initCluster' (hash
secret_shares=secret_shares
secret_threshold=secret_threshold
pgp_keys=pgp_keys
use_pgp=use_pgp
use_pgp_for_root=use_pgp_for_root
root_token_pgp_key=root_token_pgp_key
)
on="submit"
}}
id="init"
id="init"
>
<div class="box is-marginless is-shadowless">
<MessageError @errors={{errors}} />
<div class="field">
<label for="key-shares" class="is-label">
<label
for="key-shares"
class="is-label"
>
Key Shares
</label>
<div class="control">
{{input class="input" autocomplete="off" name="key-shares" type="number" step="1" min="1" pattern="[0-9]*" value=secret_shares}}
{{input
data-test-key-shares="true"
class="input"
autocomplete="off"
name="key-shares"
type="number"
step="1"
min="1"
pattern="[0-9]*"
value=secret_shares
}}
</div>
<p class="help has-text-grey">
The number of key shares to split the master key into
</p>
</div>
<div class="field">
<label for="key-threshold" class="is-label">
<label
for="key-threshold"
class="is-label"
>
Key Threshold
</label>
<div class="control">
{{input class="input" autocomplete="off" name="key-threshold" type="number" step="1" min="1" pattern="[0-9]*" value=secret_threshold}}
{{input
data-test-key-threshold="true"
class="input" autocomplete="off"
name="key-threshold"
type="number"
step="1"
min="1"
pattern="[0-9]*"
value=secret_threshold
}}
</div>
<p class="help has-text-grey">
The number of key shares required to reconstruct the master key
</p>
</div>

<ToggleButton
@openLabel="Encrypt Output with PGP"
@closedLabel="Encrypt Output with PGP"
@toggleTarget={{this}}
@toggleAttr="use_pgp"
@class="is-block"
/>
/>
{{#if use_pgp}}
<div class="box init-box">
<p class="help has-text-grey">
The output unseal keys will be encrypted and hex-encoded, in order, with the given public keys.
</p>
<PgpList @listLength={{secret_shares}} @onDataUpdate={{action 'setKeys'}} />
<PgpList
@listLength={{secret_shares}}
@onDataUpdate={{action 'setKeys'}}
/>
</div>
{{/if}}
<ToggleButton
Expand All @@ -137,24 +198,27 @@
<p class="help has-text-grey">
The root unseal key will be encrypted and hex-encoded with the given public key.
</p>
<PgpList @listLength=1 @onDataUpdate={{action 'setRootKey'}} />
<PgpList
@listLength=1
@onDataUpdate={{action 'setRootKey'}}
/>
</div>
{{/if}}
</div>
<div class="box is-marginless is-shadowless">
<button
data-test-init-submit
type="submit"
class="button is-primary {{if loading 'is-loading'}}"
disabled={{loading}}
>
Initialize
</button>

<div class="init-illustration">
{{partial "svg/initialize"}}
</div>
</div>
</form>
</Page.content>
{{/if}}
</SplashPage>
</SplashPage>

Choose a reason for hiding this comment

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

Intentional lack of newline or fallout from switching to VSCode 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😱 also another VSCode thing which I think I've fixed...