Merge pull request #617 from hashicorp/connect-dialog-based-on-feature-session-creds
feat: Update connect dialog with credentials api response
This commit is contained in:
10 files changed
+228
-88
No files matched your search
@@ -108,3 +108,7 @@ email:
|
||||
label: Email
|
||||
full_name:
|
||||
label: Full Name
|
||||
key:
|
||||
label: Key
|
||||
value:
|
||||
label: Value
|
||||
@@ -150,8 +150,14 @@ session:
|
||||
credential:
|
||||
title: Credential
|
||||
title_plural: Credentials
|
||||
secret:
|
||||
label: Secret
|
||||
credential_library:
|
||||
title: Credential Library
|
||||
actions:
|
||||
detail: Credential library details
|
||||
raw-api:
|
||||
show: View raw API output
|
||||
hide: Hide raw API output
|
||||
org:
|
||||
title: Org
|
||||
title_plural: Orgs
|
||||
@@ -261,3 +267,4 @@ target:
|
||||
add:
|
||||
title: Add Host Sets
|
||||
description: Select host sets to assign to this target.
|
||||
secret: ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class='hidden-secret'>
|
||||
{{! TODO: The span wrap within a div because later we will add the toggle secret icon/button}}
|
||||
<div>
|
||||
<span>{{t 'resources.target.host-set.secret'}}</span>
|
||||
</div>
|
||||
<Copyable
|
||||
@text={{@secret}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
/>
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
import { helper } from '@ember/component/helper';
|
||||
|
||||
/**
|
||||
* Helper to convert json object to string for display purposes.
|
||||
*/
|
||||
export default helper(function rawJson([json]) {
|
||||
return JSON.stringify(json, null, ' ');
|
||||
});
|
||||
@@ -414,6 +414,11 @@ $chevron-down: url("data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%231
|
||||
.reveal-trigger-text-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +434,7 @@ $chevron-down: url("data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%231
|
||||
border-bottom: sizing.rems(xxxxs) solid var(--ui-gray-subtler-3);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: sizing.rems(s) sizing.rems(s);
|
||||
padding: sizing.rems(s) sizing.rems(s) sizing.rems(s) sizing.rems(m);
|
||||
|
||||
h2 {
|
||||
@include type.type(s, normal);
|
||||
@@ -451,4 +456,21 @@ $chevron-down: url("data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%231
|
||||
border-top: sizing.rems(xxxxs) solid var(--ui-gray-subtler-3);
|
||||
padding: sizing.rems(s);
|
||||
}
|
||||
|
||||
// Allow text wrapping for copyable content in table
|
||||
.rose-table .copyable {
|
||||
white-space: inherit;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-secret {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--ui-gray-subtler-2);
|
||||
|
||||
.rose-button-ghost {
|
||||
color: var(--ui-gray-subtler-1);
|
||||
}
|
||||
}
|
||||
@@ -18,87 +18,122 @@
|
||||
@dismissButtonText={{t 'actions.ok'}}
|
||||
>
|
||||
<:body>
|
||||
<h3>{{t 'resources.target.messages.proxy_url.title'}}
|
||||
{{!-- (<code>{{t 'resources.target.types.tcp'}}</code>)</h3> --}}
|
||||
({{t 'resources.target.types.tcp'}})</h3>
|
||||
<h3>
|
||||
{{t 'resources.target.messages.proxy_url.title'}}
|
||||
({{t 'resources.target.types.tcp'}})
|
||||
</h3>
|
||||
<p>
|
||||
<Copyable
|
||||
@text={{session.proxy}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{session.proxy_address}}:{{session.proxy_port}}</code>
|
||||
<code>{{session.proxy}}</code>
|
||||
</Copyable>
|
||||
</p>
|
||||
|
||||
<Rose::Separator />
|
||||
{{#if session.credentials}}
|
||||
<Rose::Separator />
|
||||
|
||||
{{! TODO: Conditional for when credentials aren't available
|
||||
older versions of cli }}
|
||||
<h3>{{t 'resources.session.credential.title_plural'}}</h3>
|
||||
{{!-- <Card
|
||||
@heading={{t 'resources.session.credential.title'}}
|
||||
@icon='app-icons/credentials'
|
||||
>
|
||||
<:header>
|
||||
<Rose::Dropdown
|
||||
@text={{t 'resources.session.credential.actions.detail'}}
|
||||
@style='condensed'
|
||||
@dropdownRight={{true}}
|
||||
as |dropdown|
|
||||
<h3>{{t 'resources.session.credential.title_plural'}}</h3>
|
||||
|
||||
{{#each session.credentials as |credential|}}
|
||||
<Card
|
||||
@heading={{concat
|
||||
(t 'resources.session.credential.title')
|
||||
' ('
|
||||
credential.purpose
|
||||
')'
|
||||
}}
|
||||
@icon='app-icons/credential'
|
||||
>
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.id.label'}}</:key>
|
||||
<:value>cl_nbv9375hLHs</:value>
|
||||
</dropdown.key-value>
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.name.label'}}</:key>
|
||||
<:value>Key/Value</:value>
|
||||
</dropdown.key-value>
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.description.label'}}</:key>
|
||||
<:value>Lorem ipsum dolor, sit amet consectetur adipisicing
|
||||
elit. Ut nobis, nemo cum omnis saepe reprehenderit eaque
|
||||
non odit iste magni quod voluptatem soluta dolor beatae
|
||||
libero consequatur, perferendis rem molestias.</:value>
|
||||
</dropdown.key-value>
|
||||
</Rose::Dropdown>
|
||||
</:header>
|
||||
<:body>
|
||||
{{! TODO: Iterate through all credentials }}
|
||||
<Rose::Table @style='condensed' as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell>Key</row.headerCell>
|
||||
<row.headerCell colspan='2'>Value</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
<body.row as |row|>
|
||||
<row.headerCell>foo</row.headerCell>
|
||||
<row.cell>Value</row.cell>
|
||||
</body.row>
|
||||
<body.row as |row|>
|
||||
<row.headerCell>ttl</row.headerCell>
|
||||
<row.cell>Test</row.cell>
|
||||
</body.row>
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
</:body>
|
||||
<:footer>
|
||||
<Reveal
|
||||
@textWhenOpen='Hide content'
|
||||
@textWhenClose='View content'
|
||||
>
|
||||
<pre>
|
||||
<code>
|
||||
{ "auth": null, "lease_duration": 3600, "lease_id": "",
|
||||
"renewable": false }
|
||||
</code>
|
||||
</pre>
|
||||
</Reveal>
|
||||
</:footer>
|
||||
</Card> --}}
|
||||
<:header>
|
||||
<Rose::Dropdown
|
||||
@text={{t
|
||||
'resources.session.credential.credential_library.title'
|
||||
}}
|
||||
@style='condensed'
|
||||
@dropdownRight={{true}}
|
||||
@ignoreClickInside={{true}}
|
||||
as |dropdown|
|
||||
>
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.id.label'}}</:key>
|
||||
<:value>
|
||||
<Copyable
|
||||
@text={{credential.library.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{credential.library.id}}</code>
|
||||
</Copyable>
|
||||
</:value>
|
||||
</dropdown.key-value>
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.type.label'}}</:key>
|
||||
<:value>{{credential.library.type}}</:value>
|
||||
</dropdown.key-value>
|
||||
{{#if credential.library.name}}
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.name.label'}}</:key>
|
||||
<:value>{{credential.library.name}}</:value>
|
||||
</dropdown.key-value>
|
||||
{{/if}}
|
||||
{{#if credential.library.description}}
|
||||
<dropdown.key-value>
|
||||
<:key>{{t 'form.description.label'}}</:key>
|
||||
<:value>{{credential.library.description}}</:value>
|
||||
</dropdown.key-value>
|
||||
{{/if}}
|
||||
</Rose::Dropdown>
|
||||
</:header>
|
||||
<:body>
|
||||
{{#if credential.secrets}}
|
||||
<Rose::Table @style='condensed' as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell>{{t
|
||||
'form.key.label'
|
||||
}}</row.headerCell>
|
||||
<row.headerCell colspan='2'>{{t
|
||||
'form.value.label'
|
||||
}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
{{#each credential.secrets as |secret|}}
|
||||
<body.row as |row|>
|
||||
<row.headerCell>{{secret.key}}</row.headerCell>
|
||||
<row.cell colspan='2'>
|
||||
<Copyable
|
||||
@text={{secret.value}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
{{secret.value}}
|
||||
</Copyable>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
{{/if}}
|
||||
</:body>
|
||||
<:footer>
|
||||
<Reveal
|
||||
@textWhenOpen={{t
|
||||
'resources.session.credential.actions.raw-api.hide'
|
||||
}}
|
||||
@textWhenClose={{t
|
||||
'resources.session.credential.actions.raw-api.show'
|
||||
}}
|
||||
>
|
||||
<pre>{{raw-json credential.rawCredential}}</pre>
|
||||
</Reveal>
|
||||
</:footer>
|
||||
</Card>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</:body>
|
||||
<:footer>
|
||||
<div>
|
||||
@@ -116,4 +151,4 @@
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
|
||||
{{outlet}}
|
||||
{{outlet}}
|
||||
@@ -48,6 +48,10 @@ const extract = (artifactPath, destination) => {
|
||||
|
||||
module.exports = {
|
||||
setup: async () => {
|
||||
if (process.env.BYPASS_CLI_SETUP) {
|
||||
console.warn('WARNING: Bypassing cli setup');
|
||||
return;
|
||||
}
|
||||
const artifactPath = await downloadArtifact(artifactVersion);
|
||||
await extract(artifactPath, artifactDestination);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Component | hidden-secret', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders with a secret', async function (assert) {
|
||||
assert.expect(2);
|
||||
await render(hbs`
|
||||
<HiddenSecret @secret='AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI' />
|
||||
`);
|
||||
|
||||
assert.ok(find('.hidden-secret'));
|
||||
assert.equal(
|
||||
find('.hidden-secret > div > span').textContent.trim(),
|
||||
'■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
|
||||
module('Integration | Helper | raw-json', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
this.set('inputValue', {});
|
||||
await render(hbs`{{raw-json inputValue}}`);
|
||||
assert.equal(this.element.textContent.trim(), '{}');
|
||||
this.set('inputValue', { key: 'value', nestedKey: { key: 'value' } });
|
||||
assert.equal(
|
||||
this.element.textContent.trim(),
|
||||
`{\n "key": "value",\n "nestedKey": {\n "key": "value"\n }\n}`
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -3671,7 +3671,7 @@ agent-base@4, agent-base@^4.3.0:
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
agent-base@6:
|
||||
agent-base@6, agent-base@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
|
||||
@@ -6360,9 +6360,9 @@ caniuse-api@^3.0.0:
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157, caniuse-lite@^1.0.30001219:
|
||||
version "1.0.30001235"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001235.tgz#ad5ca75bc5a1f7b12df79ad806d715a43a5ac4ed"
|
||||
integrity sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==
|
||||
version "1.0.30001239"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz#66e8669985bb2cb84ccb10f68c25ce6dd3e4d2b8"
|
||||
integrity sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ==
|
||||
|
||||
capture-exit@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -15671,7 +15671,16 @@ npm-package-arg@^7.0.0:
|
||||
semver "^5.6.0"
|
||||
validate-npm-package-name "^3.0.0"
|
||||
|
||||
npm-package-arg@^8.0.0, npm-package-arg@^8.1.0:
|
||||
npm-package-arg@^8.0.0:
|
||||
version "8.1.5"
|
||||
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44"
|
||||
integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==
|
||||
dependencies:
|
||||
hosted-git-info "^4.0.1"
|
||||
semver "^7.3.4"
|
||||
validate-npm-package-name "^3.0.0"
|
||||
|
||||
npm-package-arg@^8.1.0:
|
||||
version "8.1.4"
|
||||
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.4.tgz#8001cdbc4363997b8ef6c6cf7aaf543c5805879d"
|
||||
integrity sha512-xLokoCFqj/rPdr3LvcdDL6Kj6ipXGEDHD/QGpzwU6/pibYUOXmp5DBmg76yukFyx4ZDbrXNOTn+BPyd8TD4Jlw==
|
||||
@@ -19098,11 +19107,11 @@ socks-proxy-agent@^4.0.0:
|
||||
socks "~2.3.2"
|
||||
|
||||
socks-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60"
|
||||
integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e"
|
||||
integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==
|
||||
dependencies:
|
||||
agent-base "6"
|
||||
agent-base "^6.0.2"
|
||||
debug "4"
|
||||
socks "^2.3.3"
|
||||
|
||||
@@ -21634,9 +21643,9 @@ write@^0.2.1:
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
ws@^7.4.5, ws@^7.4.6, ws@~7.4.2:
|
||||
version "7.4.6"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
|
||||
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.0.tgz#0033bafea031fb9df041b2026fc72a571ca44691"
|
||||
integrity sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==
|
||||
|
||||
x-is-string@^0.1.0:
|
||||
version "0.1.0"
|
||||
@@ -21744,9 +21753,9 @@ yaml@^1.10.0, yaml@^1.7.2:
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
||||
yargs-parser@20.2.4, yargs-parser@^15.0.1, yargs-parser@^18.1.2, yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^7.0.0, yargs-parser@^9.0.2, yargs-parser@~20.2.7:
|
||||
version "20.2.7"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
||||
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
||||
version "20.2.9"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs-unparser@2.0.0:
|
||||
version "2.0.0"
|
||||
|
||||
Reference in new issue
Block a user