Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
002f64d676 | ||
|
|
c09efbae10 | ||
|
|
060f995f94 | ||
|
|
f1c5c99664 | ||
|
|
af5fb8e814 | ||
|
|
cf5334556f | ||
|
|
5c6c9bb69f | ||
|
|
26a77edbc7 | ||
|
|
3fc865d226 | ||
|
|
47d7ceccf7 | ||
|
|
38df28be55 | ||
|
|
6d7c86a08c | ||
|
|
58a31b880b | ||
|
|
453ab7911d | ||
|
|
93c8d481fd | ||
|
|
956f6fd04d | ||
|
|
912be13744 | ||
|
|
fc1b91c8f9 | ||
|
|
8e40b01caf | ||
|
|
20181c978f | ||
|
|
db78f1ae4d | ||
|
|
592bb15022 | ||
|
|
f002e14673 | ||
|
|
a1b455e5eb | ||
|
|
786e6130cd | ||
|
|
4db8b8e1e7 | ||
|
|
4be8d10323 | ||
|
|
c79a1fca79 | ||
|
|
d2d332b7d1 | ||
|
|
022ac0fffe | ||
|
|
f3622fb92b | ||
|
|
f8b5dcd824 | ||
|
|
056008e13e | ||
|
|
ea03d6e488 |
No files matched your search
@@ -12,14 +12,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn install
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
@@ -37,17 +37,17 @@ jobs:
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn run build:ui:admin:oss
|
||||
- name: Upload artifact admin-ui
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
with:
|
||||
name: admin-ui
|
||||
path: ./ui/admin/dist/
|
||||
- name: Upload artifact OSS admin UI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
with:
|
||||
name: admin-ui-oss
|
||||
path: ./ui/admin/dist/
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
@@ -65,12 +65,12 @@ jobs:
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn run build:ui:admin:enterprise
|
||||
- name: Upload artifact enterprise admin UI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
with:
|
||||
name: admin-ui-ent
|
||||
path: ./ui/admin/dist/
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
@@ -88,12 +88,12 @@ jobs:
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn run build:ui:admin:hcp
|
||||
- name: Upload artifact HCP admin UI
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
with:
|
||||
name: admin-ui-hcp
|
||||
path: ./ui/admin/dist/
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@4b6aa0b07da05d6e43d0e5f9c8596a6532ce1c85 # codeql-bundle-v2.15.3
|
||||
uses: github/codeql-action/init@e6a47e25652c5dbefe5b65d3b8e8dab0e9364b21 # codeql-bundle-v2.16.0
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -54,4 +54,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@4b6aa0b07da05d6e43d0e5f9c8596a6532ce1c85 # codeql-bundle-v2.15.3
|
||||
uses: github/codeql-action/analyze@e6a47e25652c5dbefe5b65d3b8e8dab0e9364b21 # codeql-bundle-v2.16.0
|
||||
@@ -7,14 +7,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn install
|
||||
@@ -25,14 +25,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn run compliance:licenses
|
||||
@@ -44,14 +44,14 @@ jobs:
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn lint
|
||||
@@ -63,12 +63,12 @@ jobs:
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
- uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
with:
|
||||
node-version: 16
|
||||
- run: yarn test
|
||||
@@ -21,6 +21,14 @@ export default class SessionRecordingAbility extends ModelAbility {
|
||||
return !this.model.isUnknown && super.canRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only "known" session recording types may be deleted.
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canDelete() {
|
||||
return !this.model.isUnknown && super.canDelete && this.model.isAvailable;
|
||||
}
|
||||
|
||||
get canDownload() {
|
||||
return this.hasAuthorizedAction('download');
|
||||
}
|
||||
|
||||
@@ -75,6 +75,18 @@ export default class GeneratedCredentialLibraryModel extends BaseModel {
|
||||
})
|
||||
path;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault-generic',
|
||||
description: 'It indicates the type of credential the library returns.',
|
||||
})
|
||||
credential_type;
|
||||
|
||||
@attr('object', {
|
||||
for: 'vault-generic',
|
||||
description: 'It indicates the credential mapping overrides.',
|
||||
})
|
||||
credential_mapping_overrides;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault-ssh-certificate',
|
||||
isNestedAttribute: true,
|
||||
|
||||
@@ -11,6 +11,18 @@ import GeneratedCredentialLibraryModel from '../generated/models/credential-libr
|
||||
export const options = {
|
||||
http_method: ['GET', 'POST'],
|
||||
key_type: ['ed25519', 'ecdsa', 'rsa'],
|
||||
credential_types: ['ssh_private_key', 'username_password'],
|
||||
mapping_overrides: {
|
||||
username_password: {
|
||||
username_attribute: 'Username',
|
||||
password_attribute: 'Password',
|
||||
},
|
||||
ssh_private_key: {
|
||||
private_key_attribute: 'Private Key',
|
||||
private_key_passphrase_attribute: 'Private Key Passphrase',
|
||||
username_attribute: 'Username',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC = 'vault-generic';
|
||||
|
||||
@@ -7,6 +7,7 @@ import ApplicationSerializer from './application';
|
||||
import {
|
||||
TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
||||
TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
||||
options,
|
||||
} from '../models/credential-library';
|
||||
|
||||
export default class CredentialLibrarySerializer extends ApplicationSerializer {
|
||||
@@ -31,9 +32,34 @@ export default class CredentialLibrarySerializer extends ApplicationSerializer {
|
||||
return super.serialize(...arguments);
|
||||
}
|
||||
}
|
||||
serializeAttribute(snapshot, json) {
|
||||
const value = super.serializeAttribute(...arguments);
|
||||
const { credential_type, type, credential_mapping_overrides, isNew } =
|
||||
snapshot.record;
|
||||
if (
|
||||
type === TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC &&
|
||||
credential_mapping_overrides &&
|
||||
credential_type &&
|
||||
!isNew
|
||||
) {
|
||||
// API expects to send null to fields if it is undefined or deleted
|
||||
json.credential_mapping_overrides = Object.keys(
|
||||
options.mapping_overrides[credential_type],
|
||||
).reduce((obj, key) => {
|
||||
if (credential_mapping_overrides[key]) {
|
||||
obj[key] = credential_mapping_overrides[key];
|
||||
} else {
|
||||
obj[key] = null;
|
||||
}
|
||||
return obj;
|
||||
}, {});
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
serializeVaultGeneric() {
|
||||
const serialized = super.serialize(...arguments);
|
||||
|
||||
if (serialized.attributes) {
|
||||
// Set `http_request_body` only if `http_method` is POST
|
||||
// otherwise set to null to have the field removed
|
||||
|
||||
@@ -798,6 +798,8 @@ function routes() {
|
||||
},
|
||||
);
|
||||
|
||||
this.del('/session-recordings/:id');
|
||||
|
||||
/* Uncomment the following line and the Response import above
|
||||
* Then change the response code to simulate error responses.
|
||||
* this.get('/scopes', () => new Response(505));
|
||||
|
||||
@@ -11,12 +11,18 @@ import {
|
||||
TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
||||
TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
||||
TYPES_CREDENTIAL_LIBRARY,
|
||||
options,
|
||||
} from 'api/models/credential-library';
|
||||
|
||||
export default factory.extend({
|
||||
id: () => generateId('cl_'),
|
||||
type: (i) => TYPES_CREDENTIAL_LIBRARY[i % TYPES_CREDENTIAL_LIBRARY.length],
|
||||
|
||||
credential_type(i) {
|
||||
if (this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC) {
|
||||
return options.credential_types[i % options.credential_types.length];
|
||||
}
|
||||
},
|
||||
authorized_actions: () =>
|
||||
permissions.authorizedActionsFor('credential-library') || [
|
||||
'no-op',
|
||||
|
||||
@@ -60,6 +60,7 @@ export default factory.extend({
|
||||
'read',
|
||||
'download',
|
||||
'reapply-storage-policy',
|
||||
'delete',
|
||||
],
|
||||
|
||||
withNonExistingUserAndTarget: trait({
|
||||
|
||||
@@ -14,6 +14,17 @@ export default ApplicationSerializer.extend({
|
||||
arguments,
|
||||
);
|
||||
json.credential_store_id = model.credentialStoreId;
|
||||
|
||||
// BE API only updates these fields if there's an update mask, otherwise they remain unmodified
|
||||
// but we don't need this flow in our mocks, so we are deleting fields with null value
|
||||
|
||||
if (json.credential_mapping_overrides) {
|
||||
Object.keys(json.credential_mapping_overrides).forEach((key) => {
|
||||
if (json.credential_mapping_overrides[key] === null) {
|
||||
delete json.credential_mapping_overrides[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
return json;
|
||||
},
|
||||
});
|
||||
@@ -5,6 +5,11 @@
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import {
|
||||
STATE_SESSION_RECORDING_AVAILABLE,
|
||||
STATE_SESSION_RECORDING_STARTED,
|
||||
TYPE_SESSION_RECORDING_SSH,
|
||||
} from 'api/models/session-recording';
|
||||
|
||||
module('Unit | Ability | session-recording', function (hooks) {
|
||||
setupTest(hooks);
|
||||
@@ -49,4 +54,36 @@ module('Unit | Ability | session-recording', function (hooks) {
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test('can delete a session with proper authorization and in available state', function (assert) {
|
||||
const recordingNotinAvaialableState = store.createRecord(
|
||||
'session-recording',
|
||||
{
|
||||
authorized_actions: ['delete'],
|
||||
type: TYPE_SESSION_RECORDING_SSH,
|
||||
state: STATE_SESSION_RECORDING_STARTED,
|
||||
},
|
||||
);
|
||||
const recordingInAvailableState = store.createRecord('session-recording', {
|
||||
authorized_actions: ['delete'],
|
||||
type: TYPE_SESSION_RECORDING_SSH,
|
||||
state: STATE_SESSION_RECORDING_AVAILABLE,
|
||||
});
|
||||
assert.false(
|
||||
canService.can('delete session-recording', recordingNotinAvaialableState),
|
||||
);
|
||||
assert.true(
|
||||
canService.can('delete session-recording', recordingInAvailableState),
|
||||
);
|
||||
});
|
||||
|
||||
test('can re-apply Storage policy with proper authorization', function (assert) {
|
||||
const recording = store.createRecord('session', {
|
||||
authorized_actions: ['reapply-storage-policy'],
|
||||
});
|
||||
|
||||
assert.true(
|
||||
canService.can('reapplyStoragePolicy session-recording', recording),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -23,6 +23,8 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
version: 1,
|
||||
credential_type: 'ssh_private_key',
|
||||
credential_mapping_overrides: { username_attribute: 'user' },
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
const serializedRecord = serializer.serialize(snapshot);
|
||||
@@ -32,6 +34,10 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
version: 1,
|
||||
credential_type: 'ssh_private_key',
|
||||
credential_mapping_overrides: {
|
||||
username_attribute: 'user',
|
||||
},
|
||||
attributes: {
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
@@ -54,6 +60,8 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
version: 1,
|
||||
credential_type: 'ssh_private_key',
|
||||
credential_mapping_overrides: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -65,6 +73,12 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
credential_store_id: null,
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
credential_type: 'ssh_private_key',
|
||||
credential_mapping_overrides: {
|
||||
private_key_attribute: null,
|
||||
private_key_passphrase_attribute: null,
|
||||
username_attribute: null,
|
||||
},
|
||||
attributes: {
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
@@ -80,6 +94,8 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
||||
http_method: '',
|
||||
path: null,
|
||||
credential_type: null,
|
||||
credential_mapping_overrides: {},
|
||||
});
|
||||
const vaultSSHCertificateRecord = store.createRecord('credential-library', {
|
||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
||||
@@ -99,6 +115,8 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
description: null,
|
||||
name: null,
|
||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
||||
credential_type: null,
|
||||
credential_mapping_overrides: {},
|
||||
});
|
||||
assert.deepEqual(serializedVaultSSHCertificateRecord, {
|
||||
attributes: {
|
||||
@@ -138,6 +156,8 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
description: null,
|
||||
name: null,
|
||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
||||
credential_type: null,
|
||||
credential_mapping_overrides: {},
|
||||
},
|
||||
'http_request_body attribute is not expected',
|
||||
);
|
||||
@@ -156,6 +176,8 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
description: null,
|
||||
name: null,
|
||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
||||
credential_type: null,
|
||||
credential_mapping_overrides: {},
|
||||
},
|
||||
'http_request_body attribute is expected',
|
||||
);
|
||||
|
||||
@@ -48,6 +48,8 @@ session_max_seconds:
|
||||
session_connection_limit:
|
||||
label: Maximum Connections
|
||||
help: The maximum number of connections allowed per session. For unlimited, specify "-1".
|
||||
session_id:
|
||||
label: Session ID
|
||||
worker_release_version:
|
||||
label: Release Version
|
||||
help: The version of the Boundary binary the worker is running.
|
||||
@@ -58,8 +60,6 @@ worker_last_seen:
|
||||
help: Last time the worker reported status.
|
||||
worker_address:
|
||||
help: URL and port for this worker.
|
||||
worker_type:
|
||||
help: Type of worker
|
||||
host_set:
|
||||
label: Host Set
|
||||
grant_scope:
|
||||
|
||||
@@ -354,6 +354,8 @@ session-recording:
|
||||
up: '{bytes} up'
|
||||
down: '{bytes} down'
|
||||
duration: '{time} duration'
|
||||
questions:
|
||||
delete: Are you sure you want to delete this recording?
|
||||
connection:
|
||||
title: Connection
|
||||
title_index: Connection {index}
|
||||
@@ -761,6 +763,12 @@ credential-library:
|
||||
description: A credential library is a resource that provides credentials.
|
||||
titles:
|
||||
new: New Credential Library
|
||||
ssh_private_key: SSH Private Key
|
||||
username_password: Username & Password
|
||||
username_attribute: Username
|
||||
password_attribute: Password
|
||||
private_key_passphrase_attribute: Private Key Passphrase
|
||||
private_key_attribute: Private Key
|
||||
actions:
|
||||
create: New Credential Library
|
||||
delete: Delete Credential Library
|
||||
@@ -772,6 +780,12 @@ credential-library:
|
||||
vault_path:
|
||||
label: Vault Path
|
||||
help: The path the library uses when requesting credentials from Vault.
|
||||
credential_type:
|
||||
label: Credential Type
|
||||
help: Specify the type of credential this library will issue. This must be set to use credential injection. After this data is saved, it cannot be changed later.
|
||||
credential_mapping_overrides:
|
||||
label: Credential mapping overrides
|
||||
help: Specify the credential fields to use instead of the defaults
|
||||
http_method:
|
||||
label: HTTP Method
|
||||
help: The HTTP method the library uses when requesting credentials from Vault.
|
||||
@@ -839,7 +853,6 @@ credential:
|
||||
help: The private key to use when connecting with this credential store.
|
||||
private_key_passphrase:
|
||||
label: Passphrase
|
||||
help: Optional.
|
||||
json:
|
||||
label: JSON
|
||||
help: This is the JSON blob that provides credentials to the host. After this data is saved, you will not be able to edit it again without replacing it.
|
||||
@@ -917,7 +930,7 @@ worker:
|
||||
title: 1. Configure your new worker
|
||||
create_directory: Create a configuration file in a new directory on your server
|
||||
create_config: 'Open the file with a text editor, such as Vi. Paste the following configuration into the worker config file:'
|
||||
save_config: Save the configuration in your `pki-worker.hcl` file.
|
||||
save_config: Save the configuration in your <code>pki-worker.hcl</code> file.
|
||||
2:
|
||||
title: 2. Install & start Boundary on your server
|
||||
run_command: 'Run this command on your server to install Boundary:'
|
||||
@@ -944,11 +957,13 @@ policy:
|
||||
create_policy_description: Enable session recording for projects in this org.
|
||||
retain_until: Retain until
|
||||
actions:
|
||||
detach: Detach Storage Policy
|
||||
delete: Delete Storage Policy
|
||||
add: Add Storage Policy
|
||||
apply: Apply the storage policy to this scope and its children
|
||||
new: Add a new storage policy
|
||||
update: Re-apply storage policy
|
||||
delete_recording: Delete recording
|
||||
questions:
|
||||
detach: Are you sure you want to detach this storage policy?
|
||||
messages:
|
||||
@@ -975,8 +990,8 @@ policy:
|
||||
label: Custom
|
||||
do_not_protect:
|
||||
label: Do not protect, allow deletion any time
|
||||
hippa:
|
||||
label: HIPPA (6 years)
|
||||
hipaa:
|
||||
label: HIPAA (6 years)
|
||||
soc:
|
||||
label: SOC 2 (7 years)
|
||||
deletion_policy_options:
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@embroider/test-setup": "^2.1.1",
|
||||
"@hashicorp/design-system-components": "^3.2.0",
|
||||
"@hashicorp/design-system-components": "^3.5.0",
|
||||
"codemirror": "5.65.7",
|
||||
"ember-auto-import": "^2.6.3",
|
||||
"ember-cli-babel": "^7.26.11",
|
||||
|
||||
@@ -29,4 +29,14 @@ export default class OverrideSessionRecordingAbility extends SessionRecordingAbi
|
||||
? this.hasAuthorizedAction('reapply-storage-policy')
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This override ensures that session recordings may be deleted only if the
|
||||
* session-recording feature flag is enabled.
|
||||
*/
|
||||
get canDelete() {
|
||||
return this.features.isEnabled('ssh-session-recording')
|
||||
? super.canDelete
|
||||
: false;
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='account' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.account.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -13,10 +13,4 @@
|
||||
<DocLink @doc='auth-method' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.auth-method.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
+1
-7
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='managed-groups' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.managed-group.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -1,35 +0,0 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: MPL-2.0
|
||||
}}
|
||||
|
||||
<span
|
||||
id={{this.id}}
|
||||
class='copyable'
|
||||
{{did-insert this.register}}
|
||||
{{will-destroy this.tearDown}}
|
||||
>
|
||||
|
||||
{{#if this.copied}}
|
||||
<mark class='copyable-content'>
|
||||
{{yield}}
|
||||
</mark>
|
||||
{{else}}
|
||||
<span class='copyable-content'>
|
||||
{{yield}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.isClipboardLibrarySupported}}
|
||||
<Rose::Button
|
||||
id={{this.copyableButtonId}}
|
||||
aria-describedby={{this.id}}
|
||||
class='copyable-button'
|
||||
@style='ghost'
|
||||
@iconOnly={{if this.copied this.successIcon this.actionIcon}}
|
||||
title={{if this.copied this.successText this.actionText}}
|
||||
>
|
||||
{{this.actionText}}
|
||||
</Rose::Button>
|
||||
{{/if}}
|
||||
</span>
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
||||
import Component from '@glimmer/component';
|
||||
import ClipboardJS from 'clipboard';
|
||||
import { action } from '@ember/object';
|
||||
import { generateComponentID } from 'rose/utilities/component-auto-id';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { later } from '@ember/runloop';
|
||||
|
||||
export default class CopyableComponent extends Component {
|
||||
// =attributes
|
||||
|
||||
id = generateComponentID();
|
||||
copyableButtonId = `copyable-button-${this.id}`;
|
||||
|
||||
actionIcon = 'flight-icons/svg/clipboard-copy-16';
|
||||
successIcon = 'flight-icons/svg/clipboard-checked-16';
|
||||
actionText = this.args.buttonText;
|
||||
successText = this.args.acknowledgeText;
|
||||
|
||||
@tracked copied = false;
|
||||
|
||||
clipboard = null;
|
||||
|
||||
confirmCopy() {
|
||||
this.copied = true;
|
||||
later(() => (this.copied = false), 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for ClipboardJS support.
|
||||
* @return {boolean}
|
||||
*/
|
||||
get isClipboardLibrarySupported() {
|
||||
return ClipboardJS.isSupported();
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
/**
|
||||
* Initialize ClipboardJS library and register for it's events.
|
||||
*/
|
||||
@action
|
||||
register() {
|
||||
this.tearDown();
|
||||
/* istanbul ignore next */
|
||||
this.clipboard = new ClipboardJS(`#${this.copyableButtonId}`, {
|
||||
text: () => this.args.text,
|
||||
});
|
||||
/* istanbul ignore next */
|
||||
this.clipboard.on('success', (clipboardEvent) => {
|
||||
clipboardEvent.clearSelection();
|
||||
this.confirmCopy();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy ClipboardJS library instance and cancel icon timer.
|
||||
*/
|
||||
@action
|
||||
tearDown() {
|
||||
this.clipboard?.destroy();
|
||||
this.clipboard = null;
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='credential-store' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.credential-store.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -12,37 +12,35 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.type}} disabled={{form.disabled}} as |F|>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
</InfoField>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -57,24 +55,25 @@
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<form.input
|
||||
@name='issuer'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.issuer}}
|
||||
@label={{t 'form.issuer.label'}}
|
||||
@helperText={{t 'form.issuer.help'}}
|
||||
@error={{@model.errors.issuer}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.issuer}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
name='issuer'
|
||||
{{on 'input' (set-from-event @model 'issuer')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.issuer.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.issuer.help'}}</F.HelperText>
|
||||
{{#if @model.errors.issuer}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.issuer as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Checkbox::Field
|
||||
name='disable_discovered_config_validation'
|
||||
@@ -95,164 +94,86 @@
|
||||
</F.HelperText>
|
||||
</Hds::Form::Checkbox::Field>
|
||||
|
||||
<form.input
|
||||
@name='client_id'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='client_id'
|
||||
@value={{@model.client_id}}
|
||||
@label={{t 'form.client_id.label'}}
|
||||
@helperText={{t 'form.client_id.help'}}
|
||||
@error={{@model.errors.client_id}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.client_id}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'client_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.client_id.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.client_id.help'}}</F.HelperText>
|
||||
{{#if @model.errors.client_id}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.client_id as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='client_secret'
|
||||
@type='password'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='client_secret'
|
||||
@value={{@model.client_secret}}
|
||||
@label={{t 'form.client_secret.label'}}
|
||||
@helperText={{t 'form.client_secret.help'}}
|
||||
@error={{@model.errors.client_secret}}
|
||||
readonly={{false}}
|
||||
@isInvalid={{@model.errors.client_secret}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
@hasVisibilityToggle={{false}}
|
||||
as |field|
|
||||
@type='password'
|
||||
{{on 'input' (set-from-event @model 'client_secret')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.client_secret.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.client_secret.help'}}</F.HelperText>
|
||||
{{#if @model.errors.client_secret}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.client_secret as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#unless @model.isNew}}
|
||||
<form.input
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.client_secret_hmac}}
|
||||
@label={{t 'form.client_secret_hmac.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
disabled={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.client_secret_hmac.label'}}</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/unless}}
|
||||
|
||||
{{! Signing Algorithms }}
|
||||
<Rose::Form::Fieldset>
|
||||
<:title>{{t 'form.signing_algorithms.label'}}</:title>
|
||||
<:description>{{t 'form.signing_algorithms.help'}}</:description>
|
||||
<:body>
|
||||
<Form::Field::ListWrapper @layout='horizontal' @disabled={{form.disabled}}>
|
||||
<:fieldset as |F|>
|
||||
<F.Legend>
|
||||
{{t 'form.signing_algorithms.label'}}
|
||||
</F.Legend>
|
||||
<F.HelperText>
|
||||
{{t 'form.signing_algorithms.help'}}
|
||||
</F.HelperText>
|
||||
|
||||
{{#if @model.errors.signing_algorithms}}
|
||||
<Rose::Form::Errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.signing_algorithms as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</Rose::Form::Errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
<Rose::Table @style='condensed' as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row @hidden={{true}} as |row|>
|
||||
<row.headerCell>{{t 'titles.value'}}</row.headerCell>
|
||||
<row.headerCell>{{t 'titles.actions'}}</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
{{#each @model.signing_algorithms as |algorithm i|}}
|
||||
<body.row as |row|>
|
||||
<row.cell>
|
||||
</:fieldset>
|
||||
|
||||
<Hds::Form::Select::Field
|
||||
@value={{algorithm.value}}
|
||||
@isInvalid={{@model.errors.signing_algorithms}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'change' (set-from-event algorithm 'value')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label class='sr-only'>{{t
|
||||
'form.algorithm.label'
|
||||
}}</F.Label>
|
||||
<F.Options>
|
||||
{{#each this.signingAlgorithms as |algorithmOption|}}
|
||||
<option
|
||||
value={{algorithmOption}}
|
||||
selected={{eq algorithmOption algorithm.value}}
|
||||
>{{algorithmOption}}</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Field>
|
||||
|
||||
</row.cell>
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='warning'
|
||||
@iconOnly='flight-icons/svg/trash-16'
|
||||
title={{t 'actions.remove'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
false
|
||||
(if form.isEditable false true)
|
||||
}}
|
||||
{{on 'click' (fn @removeItemByIndex 'signing_algorithms' i)}}
|
||||
>
|
||||
{{t 'actions.remove'}}
|
||||
</Rose::Button>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
{{/each}}
|
||||
|
||||
<body.row as |row|>
|
||||
<row.cell>
|
||||
|
||||
<Hds::Form::Select::Field
|
||||
@value={{this.newSigningAlgorithm}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'change' (set-from-event this 'newSigningAlgorithm')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label class='sr-only'>{{t
|
||||
'resources.auth-method.titles.new-signing-algorithm'
|
||||
}}</F.Label>
|
||||
<F.Options>
|
||||
{{#each this.signingAlgorithms as |algorithmOption|}}
|
||||
<option
|
||||
value={{algorithmOption}}
|
||||
selected={{eq algorithmOption this.newSigningAlgorithm}}
|
||||
>{{algorithmOption}}</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Field>
|
||||
|
||||
</row.cell>
|
||||
<row.cell @shrink={{true}}>
|
||||
<Rose::Button
|
||||
@style='secondary'
|
||||
title={{t 'actions.add'}}
|
||||
@disabled={{if
|
||||
@model.isNew
|
||||
false
|
||||
(if form.isEditable false true)
|
||||
}}
|
||||
{{on
|
||||
'click'
|
||||
(fn
|
||||
@addStringItem 'signing_algorithms' this.newSigningAlgorithm
|
||||
)
|
||||
}}
|
||||
>
|
||||
{{t 'actions.add'}}
|
||||
</Rose::Button>
|
||||
</row.cell>
|
||||
</body.row>
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
</:body>
|
||||
</Rose::Form::Fieldset>
|
||||
<:field as |F|>
|
||||
<F.Select
|
||||
@name='signing_algorithms'
|
||||
@model={{@model}}
|
||||
@selectOptions={{this.signingAlgorithms}}
|
||||
@width='100%'
|
||||
/>
|
||||
</:field>
|
||||
</Form::Field::ListWrapper>
|
||||
|
||||
{{! Allowed Audiences }}
|
||||
<Form::Field::ListWrapper
|
||||
@@ -488,45 +409,43 @@
|
||||
|
||||
</Form::Field::ListWrapper>
|
||||
|
||||
<form.input
|
||||
@name='max_age'
|
||||
@type='number'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='max_age'
|
||||
@value={{@model.max_age}}
|
||||
@label={{t 'form.max_age.label'}}
|
||||
@helperText={{t 'form.max_age.help'}}
|
||||
@error={{@model.errors.max_age}}
|
||||
readonly={{false}}
|
||||
step='1'
|
||||
min='0'
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.max_age}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'max_age')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.max_age.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.max_age.help'}}</F.HelperText>
|
||||
{{#if @model.errors.max_age}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.max_age as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='api_url_prefix'
|
||||
@type='test'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='api_url_prefix'
|
||||
@value={{@model.api_url_prefix}}
|
||||
@label={{t 'form.api_url_prefix.label'}}
|
||||
@helperText={{t 'form.api_url_prefix.help'}}
|
||||
@error={{@model.errors.api_url_prefix}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.api_url_prefix}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'api_url_prefix')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.api_url_prefix.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.api_url_prefix.help'}}</F.HelperText>
|
||||
{{#if @model.errors.api_url_prefix}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.api_url_prefix as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Fieldset @isOptional={{true}} as |F|>
|
||||
<F.Legend>{{t 'form.prompts.label'}}</F.Legend>
|
||||
@@ -581,13 +500,14 @@
|
||||
</Hds::Form::Fieldset>
|
||||
|
||||
{{#unless @model.isNew}}
|
||||
<form.input
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.callback_url}}
|
||||
@label={{t 'form.callback_url.label'}}
|
||||
@helperText={{t 'form.callback_url.help'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
disabled={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.callback_url.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.callback_url.help'}}</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/unless}}
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
|
||||
@@ -10,49 +10,40 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.type}} disabled={{form.disabled}} as |F|>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
</InfoField>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.description.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.description.help'}}</F.HelperText>
|
||||
{{#if @model.errors.description}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.description as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
|
||||
@@ -108,6 +108,78 @@
|
||||
{{/if}}
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Select::Field
|
||||
@isOptional={{true}}
|
||||
@width='100%'
|
||||
name='credential_type'
|
||||
disabled={{or form.disabled (not @model.isNew)}}
|
||||
{{on 'input' this.selectCredentialType}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.credential-library.form.credential_type.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.credential-library.form.credential_type.help'}}
|
||||
</F.HelperText>
|
||||
<F.Options>
|
||||
<option value='' />
|
||||
|
||||
{{#each this.credentialTypes as |type|}}
|
||||
<option value={{type}} selected={{eq type @model.credential_type}}>
|
||||
{{t (concat 'resources.credential-library.titles.' type)}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
{{#if @model.errors.credential_type}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.credential_type as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::Select::Field>
|
||||
|
||||
{{#if @model.credential_type}}
|
||||
<Form::Field::ListWrapper
|
||||
@layout='horizontal'
|
||||
@isOptional={{true}}
|
||||
@disabled={{form.disabled}}
|
||||
>
|
||||
<:fieldset as |F|>
|
||||
<F.Legend>
|
||||
{{t
|
||||
'resources.credential-library.form.credential_mapping_overrides.label'
|
||||
}}
|
||||
</F.Legend>
|
||||
<F.HelperText>
|
||||
{{t
|
||||
'resources.credential-library.form.credential_mapping_overrides.help'
|
||||
}}
|
||||
</F.HelperText>
|
||||
|
||||
{{#if @model.errors.credential_mapping_overrides}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.credential_mapping_overrides as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</:fieldset>
|
||||
|
||||
<:field as |F|>
|
||||
<F.SelectText
|
||||
@name='credential_mapping_overrides'
|
||||
@selectOptions={{this.mappingOverrides}}
|
||||
@model={{@model}}
|
||||
@disabled={{form.disabled}}
|
||||
@removeDuplicates={{true}}
|
||||
@width='400px'
|
||||
/>
|
||||
</:field>
|
||||
</Form::Field::ListWrapper>
|
||||
{{/if}}
|
||||
|
||||
<Hds::Form::Radio::Group
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'http_method')}}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
options,
|
||||
TYPES_CREDENTIAL_LIBRARY,
|
||||
} from 'api/models/credential-library';
|
||||
|
||||
import { action } from '@ember/object';
|
||||
export default class FormCredentialLibraryVaultGenericComponent extends Component {
|
||||
// =properties
|
||||
/**
|
||||
@@ -16,6 +16,7 @@ export default class FormCredentialLibraryVaultGenericComponent extends Componen
|
||||
*/
|
||||
httpMethodOptions = options.http_method;
|
||||
|
||||
credentialTypes = options.credential_types;
|
||||
/**
|
||||
*
|
||||
* @type {Array.<string>}
|
||||
@@ -29,4 +30,17 @@ export default class FormCredentialLibraryVaultGenericComponent extends Componen
|
||||
get isHttpRequestBodyAllowed() {
|
||||
return this.args.model.http_method?.match(/post/i);
|
||||
}
|
||||
|
||||
get mappingOverrides() {
|
||||
return options.mapping_overrides[this.args.model.credential_type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the previously selected key value pair when toggling between credential types on a new form
|
||||
*/
|
||||
@action
|
||||
selectCredentialType({ target: { value } }) {
|
||||
this.args.model.credential_mapping_overrides = {};
|
||||
this.args.model.credential_type = value;
|
||||
}
|
||||
}
|
||||
@@ -10,30 +10,33 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
@@ -11,30 +11,33 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -76,6 +79,7 @@
|
||||
<InfoField
|
||||
@value={{t (concat 'resources.credential-store.types.' @model.type)}}
|
||||
@icon='vault'
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
@@ -85,119 +89,135 @@
|
||||
</InfoField>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<form.input
|
||||
@name='address'
|
||||
@type='text'
|
||||
|
||||
<Hds::Form::TextInput::Field
|
||||
name='address'
|
||||
@value={{@model.address}}
|
||||
@label={{t 'resources.credential-store.form.address.label'}}
|
||||
@error={{@model.errors.address}}
|
||||
@helperText={{t 'resources.credential-store.form.address.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.address}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'address')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.credential-store.form.address.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.credential-store.form.address.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.address}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.address as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (feature-flag 'vault-worker-filter')}}
|
||||
<form.input
|
||||
@name='worker_filter'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='worker_filter'
|
||||
@value={{@model.worker_filter}}
|
||||
@label={{t 'resources.credential-store.form.worker_filter.label'}}
|
||||
@error={{@model.errors.worker_filter}}
|
||||
@helperText={{t 'resources.credential-store.form.worker_filter.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'worker-filters'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.worker_filter}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'worker_filter')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.credential-store.form.worker_filter.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.credential-store.form.worker_filter.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'worker-filters'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.worker_filter}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.worker_filter as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
|
||||
{{#if (or @model.isNew form.isEditable)}}
|
||||
<form.input
|
||||
@name='token'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='token'
|
||||
@value={{@model.token}}
|
||||
@label={{t 'resources.credential-store.form.token.label'}}
|
||||
@error={{@model.errors.token}}
|
||||
@helperText={{t 'resources.credential-store.form.token.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.token}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'token')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.credential-store.form.token.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.credential-store.form.token.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.token}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.token as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
|
||||
{{#unless @model.isNew}}
|
||||
<form.input
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.token_hmac}}
|
||||
@label={{t 'resources.credential-store.form.token_hmac.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
disabled={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.credential-store.form.token_hmac.label'}}
|
||||
</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/unless}}
|
||||
|
||||
<form.input
|
||||
@name='namespace'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='namespace'
|
||||
@value={{@model.namespace}}
|
||||
@label={{t 'resources.credential-store.form.namespace.label'}}
|
||||
@error={{@model.errors.namespace}}
|
||||
@helperText={{t 'resources.credential-store.form.namespace.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.namespace}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'namespace')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.credential-store.form.namespace.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.credential-store.form.namespace.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.namespace}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.namespace as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='tls_server_name'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='tls_server_name'
|
||||
@value={{@model.tls_server_name}}
|
||||
@label={{t 'resources.credential-store.form.tls_server_name.label'}}
|
||||
@error={{@model.errors.tls_server_name}}
|
||||
@helperText={{t 'resources.credential-store.form.tls_server_name.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.tls_server_name}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'tls_server_name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.credential-store.form.tls_server_name.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.credential-store.form.tls_server_name.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.tls_server_name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.tls_server_name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Checkbox::Field
|
||||
name='tls_skip_verify'
|
||||
@@ -225,10 +245,10 @@
|
||||
</Hds::Form::Checkbox::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='client_certificate'
|
||||
@value={{@model.client_certificate}}
|
||||
@isInvalid={{@model.errors.client_certificate}}
|
||||
@isOptional={{true}}
|
||||
name='client_certificate'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -248,10 +268,10 @@
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='client_certificate_key'
|
||||
@value={{@model.client_certificate_key}}
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.client_certificate_key}}
|
||||
name='client_certificate_key'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -271,21 +291,24 @@
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
{{#unless @model.isNew}}
|
||||
<form.input
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{@model.client_certificate_key_hmac}}
|
||||
@label={{t
|
||||
'resources.credential-store.form.client_certificate_key_hmac.label'
|
||||
}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
disabled={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t
|
||||
'resources.credential-store.form.client_certificate_key_hmac.label'
|
||||
}}
|
||||
</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/unless}}
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='ca_cert'
|
||||
@value={{@model.ca_cert}}
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.ca_cert}}
|
||||
@name='ca_cert'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
@@ -11,28 +11,33 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@error={{@model.errors.name}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -48,42 +53,38 @@
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
{{#if @model.isNew}}
|
||||
<form.fieldset>
|
||||
<:body>
|
||||
<Hds::Form::RadioCard::Group as |G|>
|
||||
<G.Legend>{{t 'form.type.label'}}</G.Legend>
|
||||
{{#each @types as |credentialType|}}
|
||||
<G.RadioCard
|
||||
@name={{credentialType}}
|
||||
@value={{credentialType}}
|
||||
@checked={{eq credentialType @model.type}}
|
||||
@maxWidth='20rem'
|
||||
{{on 'input' (fn @changeType credentialType)}}
|
||||
as |R|
|
||||
>
|
||||
<R.Label>{{t
|
||||
(concat 'resources.credential.types.' credentialType)
|
||||
}}</R.Label>
|
||||
<R.Description>{{t
|
||||
(concat 'resources.credential.help.' credentialType)
|
||||
}}</R.Description>
|
||||
</G.RadioCard>
|
||||
{{/each}}
|
||||
</Hds::Form::RadioCard::Group>
|
||||
</:body>
|
||||
</form.fieldset>
|
||||
<Hds::Form::RadioCard::Group as |G|>
|
||||
<G.Legend>{{t 'form.type.label'}}</G.Legend>
|
||||
{{#each @types as |credentialType|}}
|
||||
<G.RadioCard
|
||||
@name={{credentialType}}
|
||||
@value={{credentialType}}
|
||||
@checked={{eq credentialType @model.type}}
|
||||
@maxWidth='20rem'
|
||||
{{on 'input' (fn @changeType credentialType)}}
|
||||
as |R|
|
||||
>
|
||||
<R.Label>{{t (concat 'resources.credential.types.' credentialType)}}
|
||||
</R.Label>
|
||||
<R.Description>{{t
|
||||
(concat 'resources.credential.help.' credentialType)
|
||||
}}
|
||||
</R.Description>
|
||||
</G.RadioCard>
|
||||
{{/each}}
|
||||
</Hds::Form::RadioCard::Group>
|
||||
|
||||
<form.fieldset>
|
||||
<:title>{{t 'resources.credential.form.json.label'}}</:title>
|
||||
<:description>{{t 'resources.credential.form.json.help'}}</:description>
|
||||
<:body>
|
||||
<Hds::Form::Fieldset as |F|>
|
||||
<F.Legend>{{t 'resources.credential.form.json.label'}}</F.Legend>
|
||||
<F.HelperText>{{t 'resources.credential.form.json.help'}}</F.HelperText>
|
||||
<F.Control>
|
||||
<Form::Field::JsonSecret
|
||||
@value={{@model.json_object}}
|
||||
@onInput={{fn (mut @model.json_object)}}
|
||||
@showEditButton={{false}}
|
||||
/>
|
||||
</:body>
|
||||
</form.fieldset>
|
||||
</F.Control>
|
||||
</Hds::Form::Fieldset>
|
||||
{{else}}
|
||||
<InfoField
|
||||
@value={{t (concat 'resources.credential.types.' @model.type)}}
|
||||
@@ -94,18 +95,18 @@
|
||||
</F.HelperText>
|
||||
</InfoField>
|
||||
|
||||
<form.fieldset>
|
||||
<:title>{{t 'resources.credential.form.json.label'}}</:title>
|
||||
<:description>{{t 'resources.credential.form.json.help'}}</:description>
|
||||
<:body>
|
||||
<Hds::Form::Fieldset as |F|>
|
||||
<F.Legend>{{t 'resources.credential.form.json.label'}}</F.Legend>
|
||||
<F.HelperText>{{t 'resources.credential.form.json.help'}}</F.HelperText>
|
||||
<F.Control>
|
||||
<Form::Field::JsonSecret
|
||||
@disabled={{form.disabled}}
|
||||
@value={{@model.json_object}}
|
||||
@onInput={{fn (mut @model.json_object)}}
|
||||
@showEditButton={{true}}
|
||||
/>
|
||||
</:body>
|
||||
</form.fieldset>
|
||||
</F.Control>
|
||||
</Hds::Form::Fieldset>
|
||||
{{/if}}
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
|
||||
@@ -11,28 +11,33 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@error={{@model.errors.name}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -71,6 +76,7 @@
|
||||
{{else}}
|
||||
<InfoField
|
||||
@value={{t (concat 'resources.credential.types.' @model.type)}}
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
@@ -79,29 +85,33 @@
|
||||
</InfoField>
|
||||
{{/if}}
|
||||
|
||||
<form.input
|
||||
@name='username'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='username'
|
||||
@value={{@model.username}}
|
||||
@label={{t 'resources.credential.form.username.label'}}
|
||||
@helperText={{t 'resources.credential.form.username.help'}}
|
||||
@error={{@model.errors.username}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.username}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'username')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.credential.form.username.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'resources.credential.form.username.help'}}</F.HelperText>
|
||||
{{#if @model.errors.username}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.username as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-username>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (or @model.isNew form.isEditable)}}
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{false}}
|
||||
name='private_key'
|
||||
@value={{@model.private_key}}
|
||||
@isInvalid={{@model.errors.private_key}}
|
||||
name='private_key'
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -112,30 +122,36 @@
|
||||
{{#if @model.errors.private_key}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.private_key as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
<E.Message data-test-error-message-private-key>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
<form.input
|
||||
|
||||
<Hds::Form::TextInput::Field
|
||||
name='private_key_passphrase'
|
||||
@type='password'
|
||||
@name='private_key_passphrase'
|
||||
@value={{@model.private_key_passphrase}}
|
||||
@label={{t 'resources.credential.form.private_key_passphrase.label'}}
|
||||
@helperText={{t 'resources.credential.form.private_key_passphrase.help'}}
|
||||
@error={{@model.errors.private_key_passphrase}}
|
||||
@hasVisibilityToggle={{false}}
|
||||
@isInvalid={{@model.errors.private_key_passphrase}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
autocomplete='new-password'
|
||||
as |field|
|
||||
{{on 'input' (set-from-event @model 'private_key_passphrase')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.credential.form.private_key_passphrase.label'}}
|
||||
</F.Label>
|
||||
{{#if @model.errors.private_key_passphrase}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.private_key_passphrase as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
|
||||
@@ -11,27 +11,33 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@error={{@model.errors.name}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
<Hds::Form::Textarea::Field
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<E.Message data-test-error-message-name>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -70,6 +76,7 @@
|
||||
{{else}}
|
||||
<InfoField
|
||||
@value={{t (concat 'resources.credential.types.' @model.type)}}
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
@@ -78,42 +85,50 @@
|
||||
</InfoField>
|
||||
{{/if}}
|
||||
|
||||
<form.input
|
||||
@name='username'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='username'
|
||||
@value={{@model.username}}
|
||||
@label={{t 'resources.credential.form.username.label'}}
|
||||
@helperText={{t 'resources.credential.form.username.help'}}
|
||||
@error={{@model.errors.username}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.username}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'username')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.credential.form.username.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'resources.credential.form.username.help'}}</F.HelperText>
|
||||
{{#if @model.errors.username}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.username as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (or @model.isNew form.isEditable)}}
|
||||
<form.input
|
||||
@name='password'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='password'
|
||||
@type='password'
|
||||
@value={{@model.password}}
|
||||
@label={{t 'resources.credential.form.password.label'}}
|
||||
@helperText={{t 'resources.credential.form.password.help'}}
|
||||
@error={{@model.errors.password}}
|
||||
@isInvalid={{@model.errors.password}}
|
||||
disabled={{form.disabled}}
|
||||
autocomplete='new-password'
|
||||
as |field|
|
||||
{{on 'input' (set-from-event @model 'password')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.credential.form.password.label'}}</F.Label>
|
||||
<F.HelperText>{{t
|
||||
'resources.credential.form.password.help'
|
||||
}}</F.HelperText>
|
||||
{{#if @model.errors.password}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.password as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-password>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
Textarea=(component
|
||||
'form/field/list-wrapper/textarea' disabled=@disabled
|
||||
)
|
||||
Select=(component 'form/field/list-wrapper/select' disabled=@disabled)
|
||||
SelectText=(component
|
||||
'form/field/list-wrapper/select-text' disabled=@disabled
|
||||
)
|
||||
)
|
||||
to='field'
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: MPL-2.0
|
||||
}}
|
||||
{{#let (unique-id) (unique-id) as |keyHeaderID valueHeaderID|}}
|
||||
<Hds::Table class='list-wrapper-field' name={{@name}}>
|
||||
<:head as |H|>
|
||||
<H.Tr>
|
||||
<H.Th id={{keyHeaderID}}>{{t 'form.key.label'}}</H.Th>
|
||||
<H.Th id={{valueHeaderID}}>{{t 'form.value.label'}}</H.Th>
|
||||
<H.Th>
|
||||
{{t 'titles.actions'}}
|
||||
|
||||
</H.Th>
|
||||
</H.Tr>
|
||||
</:head>
|
||||
<:body as |B|>
|
||||
{{#each-in this.options as |select val|}}
|
||||
<B.Tr>
|
||||
<B.Td>
|
||||
<Hds::Form::Select::Base
|
||||
@value={{select}}
|
||||
disabled={{@disabled}}
|
||||
@width={{@width}}
|
||||
aria-labelledby={{keyHeaderID}}
|
||||
{{on 'change' (fn this.selectChange select val)}}
|
||||
as |F|
|
||||
>
|
||||
<F.Options>
|
||||
{{#each-in @selectOptions as |key value|}}
|
||||
<option value={{key}} selected={{eq select key}}>
|
||||
{{value}}
|
||||
</option>
|
||||
{{/each-in}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Base>
|
||||
</B.Td>
|
||||
|
||||
<B.Td>
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{val}}
|
||||
@type='text'
|
||||
@width={{@width}}
|
||||
disabled={{@disabled}}
|
||||
aria-labelledby={{valueHeaderID}}
|
||||
{{on 'change' (fn this.updateInput select)}}
|
||||
/>
|
||||
</B.Td>
|
||||
|
||||
<B.Td>
|
||||
{{#if this.removeOptionByKey}}
|
||||
<Hds::Button
|
||||
data-test-remove-button={{select}}
|
||||
@text={{t 'actions.remove'}}
|
||||
@color='critical'
|
||||
@icon='trash'
|
||||
@isIconOnly={{true}}
|
||||
disabled={{@disabled}}
|
||||
{{on 'click' (fn this.removeOptionByKey select)}}
|
||||
/>
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
{{/each-in}}
|
||||
|
||||
{{#if this.showNewRow}}
|
||||
<B.Tr>
|
||||
<B.Td>
|
||||
<Hds::Form::Select::Base
|
||||
@value={{this.newOptionKey}}
|
||||
disabled={{@disabled}}
|
||||
aria-labelledby={{keyHeaderID}}
|
||||
@width={{@width}}
|
||||
{{on 'change' (set-from-event this 'newOptionKey')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Options>
|
||||
|
||||
<option hidden selected value=''>
|
||||
{{t 'titles.choose-an-option'}}
|
||||
</option>
|
||||
{{#each-in this.selectOptions as |key value|}}
|
||||
<option value={{key}} selected={{eq key this.newOptionKey}}>
|
||||
{{value}}
|
||||
</option>
|
||||
{{/each-in}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Base>
|
||||
</B.Td>
|
||||
|
||||
<B.Td>
|
||||
<Hds::Form::TextInput::Field
|
||||
@value={{this.newOptionValue}}
|
||||
@type='text'
|
||||
@width={{@width}}
|
||||
disabled={{@disabled}}
|
||||
aria-labelledby={{valueHeaderID}}
|
||||
{{on 'input' (set-from-event this 'newOptionValue')}}
|
||||
/>
|
||||
</B.Td>
|
||||
|
||||
<B.Td>
|
||||
<Hds::Button
|
||||
data-test-select-text-add-btn
|
||||
@text={{t 'actions.add'}}
|
||||
@color='secondary'
|
||||
type='button'
|
||||
disabled={{or @disabled (not this.newOptionKey)}}
|
||||
{{on 'click' this.addOption}}
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
{{/if}}
|
||||
</:body>
|
||||
</Hds::Table>
|
||||
{{/let}}
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import { set } from '@ember/object';
|
||||
|
||||
export default class MappingListComponent extends Component {
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@tracked newOptionKey = '';
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@tracked newOptionValue = '';
|
||||
|
||||
/**
|
||||
* Returns an object of key/value pair that the user enters
|
||||
* @type {object}
|
||||
*/
|
||||
get options() {
|
||||
return this.args?.options || this.args?.model?.[this.args.name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if we need to show an empty row to the users to enter more key/value pairs based on removeDuplicates arg,
|
||||
* by default it is true
|
||||
* @type {object}
|
||||
*/
|
||||
get showNewRow() {
|
||||
if (this.args.removeDuplicates) {
|
||||
return (
|
||||
Object.keys(this.options || {}).length !==
|
||||
Object.keys(this.args.selectOptions || {}).length
|
||||
);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents users from selecting duplicate keys from the select list if there's the arg is set to true
|
||||
* @type {object}
|
||||
*/
|
||||
get selectOptions() {
|
||||
const previouslySelectedKeys = Object.keys(this.options || {});
|
||||
if (this.args.removeDuplicates && previouslySelectedKeys.length) {
|
||||
const newObj = { ...this.args.selectOptions };
|
||||
for (const key of Object.keys(newObj)) {
|
||||
if (previouslySelectedKeys.includes(key)) {
|
||||
delete newObj[key];
|
||||
}
|
||||
}
|
||||
return newObj;
|
||||
} else {
|
||||
return this.args.selectOptions;
|
||||
}
|
||||
}
|
||||
// =actions
|
||||
|
||||
/**
|
||||
* Handles when then user makes changes to the select list
|
||||
* @param oldkey {string}
|
||||
* @param oldVal {string}
|
||||
*/
|
||||
@action
|
||||
selectChange(oldkey, oldVal, { target: { value: newKey } }) {
|
||||
const field = this.args.name;
|
||||
const newObj = { ...this.args.model[field], [newKey]: oldVal };
|
||||
delete newObj[oldkey];
|
||||
set(this.args.model, field, newObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles input changes
|
||||
* @param key {string}
|
||||
*/
|
||||
@action
|
||||
updateInput(key, { target: { value: newValue } }) {
|
||||
const field = this.args.name;
|
||||
this.args.model[field] = {
|
||||
...this.args.model[field],
|
||||
[key]: newValue,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* If a new key value is entered and an addOption method was specified,
|
||||
* calls addOption with the new key and value. Resets key and value.
|
||||
* Otherwise use the model argument to create the array and update the model
|
||||
*/
|
||||
|
||||
@action
|
||||
addOption() {
|
||||
if (this.args.addOption) {
|
||||
if (this.newOptionKey) {
|
||||
this.args.addOption({
|
||||
key: this.newOptionKey,
|
||||
value: this.newOptionValue,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const field = this.args.name;
|
||||
this.args.model[field] = {
|
||||
...this.args.model[field],
|
||||
[this.newOptionKey]: this.newOptionValue,
|
||||
};
|
||||
}
|
||||
|
||||
this.newOptionKey = '';
|
||||
this.newOptionValue = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* If removeOptionByIndex method was passed, use that.
|
||||
* Otherwise, use the model to remove an option by key
|
||||
* @param index {number}
|
||||
*/
|
||||
@action
|
||||
removeOptionByKey(selectedKey) {
|
||||
if (this.args.removeOptionByKey) {
|
||||
this.args.removeOptionByKey(selectedKey);
|
||||
} else {
|
||||
const field = this.args.name;
|
||||
const newObj = { ...this.args.model[field] };
|
||||
delete newObj[selectedKey];
|
||||
set(this.args.model, field, newObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: MPL-2.0
|
||||
}}
|
||||
|
||||
<Hds::Table class='list-wrapper-field' name={{@name}}>
|
||||
|
||||
<:body as |B|>
|
||||
|
||||
{{#each this.options as |select index|}}
|
||||
<B.Tr>
|
||||
<B.Td>
|
||||
<Hds::Form::Select::Base
|
||||
@value={{select.value}}
|
||||
@width={{@width}}
|
||||
disabled={{@disabled}}
|
||||
aria-label={{t 'titles.value'}}
|
||||
{{on 'change' (set-from-event select 'value')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Options>
|
||||
{{#each @selectOptions as |selectOption|}}
|
||||
<option
|
||||
value={{selectOption}}
|
||||
selected={{eq select.value selectOption}}
|
||||
>
|
||||
{{selectOption}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
</Hds::Form::Select::Base>
|
||||
</B.Td>
|
||||
|
||||
<B.Td>
|
||||
{{#if this.removeOptionByIndex}}
|
||||
<Hds::Button
|
||||
data-test-remove-option-button={{select.value}}
|
||||
@text={{t 'actions.remove'}}
|
||||
@color='critical'
|
||||
@icon='trash'
|
||||
@isIconOnly={{true}}
|
||||
disabled={{@disabled}}
|
||||
{{on 'click' (fn this.removeOptionByIndex index)}}
|
||||
/>
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
{{/each}}
|
||||
|
||||
<B.Tr>
|
||||
<B.Td>
|
||||
<Hds::Form::Select::Base
|
||||
@value={{this.newOptionValue}}
|
||||
@width={{@width}}
|
||||
disabled={{@disabled}}
|
||||
aria-label={{t 'titles.value'}}
|
||||
{{on 'change' (set-from-event this 'newOptionValue')}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
<F.Options>
|
||||
<option disabled={{@disabled}} hidden selected value=''>
|
||||
{{t 'titles.choose-an-option'}}
|
||||
</option>
|
||||
{{#each @selectOptions as |selectOption|}}
|
||||
<option
|
||||
value={{selectOption}}
|
||||
selected={{eq selectOption this.newOptionValue}}
|
||||
>
|
||||
{{selectOption}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</F.Options>
|
||||
|
||||
</Hds::Form::Select::Base>
|
||||
</B.Td>
|
||||
|
||||
<B.Td>
|
||||
<Hds::Button
|
||||
data-test-add-option-button
|
||||
@text={{t 'actions.add'}}
|
||||
@color='secondary'
|
||||
type='button'
|
||||
disabled={{or @disabled (not this.newOptionValue)}}
|
||||
{{on 'click' this.addOption}}
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
</Hds::Table>
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import { set } from '@ember/object';
|
||||
|
||||
export default class MappingListSelectComponent extends Component {
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@tracked newOptionValue = '';
|
||||
|
||||
get options() {
|
||||
return this.args.options || this.args.model[this.args.name];
|
||||
}
|
||||
|
||||
/**
|
||||
* If a new input is entered and an addOption method was specified,
|
||||
* calls addOption with the new input. Resets previous value.
|
||||
* Otherwise use the model argument to create the array and update the model
|
||||
*/
|
||||
|
||||
@action
|
||||
addOption() {
|
||||
if (this.args.addOption && this.newOptionValue) {
|
||||
this.args.addOption({
|
||||
value: this.newOptionValue,
|
||||
});
|
||||
} else {
|
||||
const field = this.args.name;
|
||||
const existingArray = this.args.model[field] ?? [];
|
||||
const newArray = [...existingArray, { value: this.newOptionValue }];
|
||||
set(this.args.model, field, newArray);
|
||||
}
|
||||
|
||||
this.newOptionValue = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* If removeOptionByIndex method was passed, use that.
|
||||
* Otherwise, use the model to remove an option by index. We recreate a new array after
|
||||
* splicing out the item so that ember is aware that the array has been modified.
|
||||
* @param index {number}
|
||||
*/
|
||||
@action
|
||||
removeOptionByIndex(index) {
|
||||
if (this.args.removeOptionByIndex) {
|
||||
this.args.removeOptionByIndex(index);
|
||||
} else {
|
||||
const field = this.args.name;
|
||||
const newArray = this.args.model[field].filter((_, i) => i !== index);
|
||||
set(this.args.model, field, newArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,30 +11,31 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
@@ -10,30 +10,31 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -94,7 +95,7 @@
|
||||
<InfoField
|
||||
@value={{t 'resources.host-catalog.types.aws'}}
|
||||
@icon='aws-color'
|
||||
disabled={{form.disabled}}
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'titles.provider'}}</F.Label>
|
||||
@@ -103,38 +104,53 @@
|
||||
</InfoField>
|
||||
{{/if}}
|
||||
|
||||
<form.input
|
||||
@name='region'
|
||||
@type='region'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='region'
|
||||
@value={{@model.region}}
|
||||
@label={{t 'resources.host-catalog.form.aws_region.label'}}
|
||||
@helperText={{t 'resources.host-catalog.form.aws_region.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.aws.region'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'region')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.host-catalog.form.aws_region.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.host-catalog.form.aws_region.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws.region'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='access_key_id'
|
||||
@type='access_key_id'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='access_key_id'
|
||||
@value={{@model.access_key_id}}
|
||||
@label={{t 'form.access_key_id.label'}}
|
||||
@helperText={{t 'form.access_key_id.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.aws'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'access_key_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.access_key_id.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.access_key_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='secret_access_key'
|
||||
@type='secret_access_key'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='secret_access_key'
|
||||
@value={{@model.secret_access_key}}
|
||||
@label={{t 'form.secret_access_key.label'}}
|
||||
@helperText={{t 'form.secret_access_key.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.aws'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'secret_access_key')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.secret_access_key.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.secret_access_key.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Checkbox::Field
|
||||
name='disable_credential_rotation'
|
||||
|
||||
@@ -10,30 +10,31 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -94,7 +95,7 @@
|
||||
<InfoField
|
||||
@value={{t 'resources.host-catalog.types.azure'}}
|
||||
@icon='azure-color'
|
||||
disabled={{form.disabled}}
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'titles.provider'}}</F.Label>
|
||||
@@ -103,49 +104,69 @@
|
||||
</InfoField>
|
||||
{{/if}}
|
||||
|
||||
<form.input
|
||||
@name='tenant_id'
|
||||
@type='tenant_id'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='tenant_id'
|
||||
@value={{@model.tenant_id}}
|
||||
@label={{t 'form.tenant_id.label'}}
|
||||
@helperText={{t 'form.tenant_id.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.azure'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'tenant_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.tenant_id.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.tenant_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.azure'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='subscription_id'
|
||||
@type='subscription_id'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='subscription_id'
|
||||
@value={{@model.subscription_id}}
|
||||
@label={{t 'form.subscription_id.label'}}
|
||||
@helperText={{t 'form.subscription_id.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.azure'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'subscription_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.subscription_id.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.subscription_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.azure'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='client_id'
|
||||
@type='client_id'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='client_id'
|
||||
@value={{@model.client_id}}
|
||||
@label={{t 'resources.host-catalog.form.azure_client_id.label'}}
|
||||
@helperText={{t 'resources.host-catalog.form.azure_client_id.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.azure'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'client_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.host-catalog.form.azure_client_id.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.host-catalog.form.azure_client_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.azure'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='secret_value'
|
||||
@type='secret_value'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='secret_value'
|
||||
@value={{@model.secret_value}}
|
||||
@label={{t 'form.secret.label'}}
|
||||
@helperText={{t 'form.secret.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'host-catalog.azure'}}
|
||||
readonly={{false}}
|
||||
/>
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'secret_value')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.secret.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.secret.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.azure'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Checkbox::Field
|
||||
name='disable_credential_rotation'
|
||||
|
||||
@@ -10,31 +10,31 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
@@ -12,30 +12,31 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.name}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -50,12 +51,9 @@
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.type}} disabled={{form.disabled}} as |F|>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
</InfoField>
|
||||
|
||||
<InfoField
|
||||
@value={{t 'descriptions.provider'}}
|
||||
@@ -125,27 +123,30 @@
|
||||
</:field>
|
||||
</Form::Field::ListWrapper>
|
||||
|
||||
<form.input
|
||||
@name='sync_interval_seconds'
|
||||
@type='number'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='sync_interval_seconds'
|
||||
@value={{@model.sync_interval_seconds}}
|
||||
@label={{t 'form.sync-interval.label'}}
|
||||
@error={{@model.errors.sync_interval_seconds}}
|
||||
@helperText={{t 'form.sync-interval.help'}}
|
||||
@link={{doc-url 'host-set.sync-interval-seconds'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
min='0'
|
||||
step='1'
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.sync_interval_seconds}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'sync_interval_seconds')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.name.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-set.sync-interval-seconds'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.sync_interval_seconds}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.sync_interval_seconds as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
|
||||
@@ -12,30 +12,31 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.name}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -50,17 +51,14 @@
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.type}} readonly={{true}} as |F|>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
</InfoField>
|
||||
|
||||
<InfoField
|
||||
@value={{t 'descriptions.provider'}}
|
||||
@icon='azure-color'
|
||||
disabled={{form.disabled}}
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'titles.provider'}}</F.Label>
|
||||
@@ -101,10 +99,10 @@
|
||||
</Form::Field::ListWrapper>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='filter'
|
||||
@value={{@model.filter_string}}
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.filter_string}}
|
||||
name='filter'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -121,27 +119,29 @@
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<form.input
|
||||
@name='sync_interval_seconds'
|
||||
@type='number'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='sync_interval_seconds'
|
||||
@value={{@model.sync_interval_seconds}}
|
||||
@label={{t 'form.sync-interval.label'}}
|
||||
@error={{@model.errors.sync_interval_seconds}}
|
||||
@helperText={{t 'form.sync-interval.help'}}
|
||||
@link={{doc-url 'host-set.sync-interval-seconds'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
min='0'
|
||||
step='1'
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.sync_interval_seconds}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'sync_interval_seconds')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.name.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-set.sync-interval-seconds'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.sync_interval_seconds}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.sync_interval_seconds as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
|
||||
@@ -11,30 +11,31 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.name}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isOptional={{true}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
@@ -11,37 +11,35 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
<Hds::Form::TextInput::Field @value={{@model.type}} disabled={{true}} as |F|>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@error={{@model.errors.name}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -56,24 +54,26 @@
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<form.input
|
||||
@name='address'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='address'
|
||||
@value={{@model.address}}
|
||||
@label={{t 'form.address.label'}}
|
||||
@error={{@model.errors.address}}
|
||||
@helperText={{t 'form.address.help'}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.address}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'address')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.address.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.address.help'}}</F.HelperText>
|
||||
{{#if @model.errors.address}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.address as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
|
||||
@@ -10,31 +10,29 @@
|
||||
@showEditToggle={{if @model.isNew false true}}
|
||||
as |form|
|
||||
>
|
||||
<form.input
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.type}} readonly={{true}} as |F|>
|
||||
<F.Label>{{t 'form.type.label'}}</F.Label>
|
||||
</InfoField>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.error.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
@@ -55,23 +53,25 @@
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
<form.input
|
||||
@name='filter'
|
||||
@type='text'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='filter'
|
||||
@value={{@model.filter_string}}
|
||||
@label={{t 'form.filter.label'}}
|
||||
@error={{@model.errors.filter_string}}
|
||||
@helperText={{t 'form.filter.help'}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.filter_string}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'filter_string')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.filter.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.filter.help'}}</F.HelperText>
|
||||
{{#if @model.errors.filter_string}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.filter_string as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (can 'save model' @model)}}
|
||||
<form.actions
|
||||
|
||||
@@ -10,7 +10,7 @@ const RETENTION_POLICY = {
|
||||
custom: 1,
|
||||
do_not_protect: 0,
|
||||
soc: 2555,
|
||||
hippa: 2190,
|
||||
hipaa: 2190,
|
||||
};
|
||||
|
||||
const DELETION_POLICY = { do_not_delete: 0, custom: 1 };
|
||||
|
||||
@@ -11,30 +11,31 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
@isOptional={{true}}
|
||||
name='description'
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
|
||||
@@ -12,45 +12,75 @@
|
||||
<h3>{{t 'resources.worker.form.steps.1.title'}}</h3>
|
||||
<div class='worker-create-section'>
|
||||
{{#if (feature-flag 'byow-pki-hcp-cluster-id')}}
|
||||
<form.input
|
||||
@name='cluster_id'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='cluster_id'
|
||||
@value={{this.clusterID}}
|
||||
@label={{t 'resources.worker.form.cluster_id.label'}}
|
||||
@helperText={{t 'resources.worker.form.cluster_id.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'worker.manage-workers'}}
|
||||
@isOptional={{true}}
|
||||
placeholder='69b6ddb3-ffec-42ab-a994-f43a6519470a'
|
||||
/>
|
||||
{{on 'input' (set-from-event this 'clusterID')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.worker.form.cluster_id.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.worker.form.cluster_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'worker.manage-workers'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
|
||||
<form.input
|
||||
@name='ip_address'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='ip_address'
|
||||
@value={{this.ipAddress}}
|
||||
@label={{t 'resources.worker.form.ip_address.label'}}
|
||||
@helperText={{t 'resources.worker.form.ip_address.help'}}
|
||||
@linkText={{t 'actions.learn-more'}}
|
||||
@link={{doc-url 'worker'}}
|
||||
@isOptional={{true}}
|
||||
placeholder='worker1.example.com'
|
||||
/>
|
||||
{{on 'input' (set-from-event this 'ipAddress')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.worker.form.ip_address.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.worker.form.ip_address.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'worker'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<form.input
|
||||
@name='config_file_path'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='config_file_path'
|
||||
@value={{this.configFilePath}}
|
||||
@label={{t 'resources.worker.form.config_file_path.label'}}
|
||||
@helperText={{t 'resources.worker.form.config_file_path.help'}}
|
||||
@isOptional={{true}}
|
||||
placeholder='/home/ubuntu/boundary'
|
||||
/>
|
||||
{{on 'input' (set-from-event this 'configFilePath')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.worker.form.config_file_path.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.worker.form.config_file_path.help'}}
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{#if (not (feature-flag 'byow-pki-hcp-cluster-id'))}}
|
||||
<form.input
|
||||
@name='initial_upstreams'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='initial_upstreams'
|
||||
@value={{this.initialUpstreams}}
|
||||
@label={{t 'resources.worker.form.initial_upstreams.label'}}
|
||||
@helperText={{t 'resources.worker.form.initial_upstreams.help'}}
|
||||
@isOptional={{true}}
|
||||
placeholder='10.0.0.1, 10.0.0.2, 10.0.0.3'
|
||||
/>
|
||||
{{on 'input' (set-from-event this 'initialUpstreams')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.worker.form.initial_upstreams.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.worker.form.initial_upstreams.help'}}
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
<Form::Field::ListWrapper @layout='horizontal' @disabled={{form.disabled}}>
|
||||
<Form::Field::ListWrapper
|
||||
@layout='horizontal'
|
||||
@disabled={{form.disabled}}
|
||||
@isOptional={{true}}
|
||||
>
|
||||
<:fieldset as |F|>
|
||||
<F.Legend>{{t 'resources.worker.form.worker_tags.label'}}</F.Legend>
|
||||
<F.HelperText>
|
||||
@@ -70,7 +100,7 @@
|
||||
</Form::Field::ListWrapper>
|
||||
|
||||
{{#if (feature-flag 'ssh-session-recording')}}
|
||||
<Hds::Form::Fieldset as |F|>
|
||||
<Hds::Form::Fieldset @isOptional={{true}} as |F|>
|
||||
<F.Legend>{{t
|
||||
'resources.worker.form.local_session_recording_storage.label'
|
||||
}}</F.Legend>
|
||||
@@ -94,80 +124,108 @@
|
||||
</F.Control>
|
||||
{{#if this.enableRecordingStoragePath}}
|
||||
<F.Control>
|
||||
<form.input
|
||||
@name='recording_storage_path'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='recording_storage_path'
|
||||
@value={{this.recording_storage_path}}
|
||||
@label={{t 'resources.worker.form.recording_storage_path.label'}}
|
||||
@helperText={{t
|
||||
'resources.worker.form.recording_storage_path.help'
|
||||
}}
|
||||
placeholder='/tmp/worker1'
|
||||
/>
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t
|
||||
'resources.worker.form.recording_storage_path.label'
|
||||
}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.worker.form.recording_storage_path.help'}}
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
</F.Control>
|
||||
{{/if}}
|
||||
</Hds::Form::Fieldset>
|
||||
{{/if}}
|
||||
|
||||
<Rose::CodeEditor @codeValue={{this.createConfigText}} as |c|>
|
||||
<c.toolbar>
|
||||
<:action>
|
||||
<span>{{t 'resources.worker.form.steps.1.create_directory'}}</span>
|
||||
</:action>
|
||||
</c.toolbar>
|
||||
<c.fieldEditor class='rose-autosize' @options={{this.shellCodeEditor}} />
|
||||
</Rose::CodeEditor>
|
||||
<p>
|
||||
{{t 'resources.worker.form.steps.1.create_directory'}}
|
||||
</p>
|
||||
|
||||
<Rose::CodeEditor @codeValue={{this.workerConfigText}} as |c|>
|
||||
<c.toolbar>
|
||||
<:action>
|
||||
<span>{{t 'resources.worker.form.steps.1.create_config'}}</span>
|
||||
</:action>
|
||||
</c.toolbar>
|
||||
<c.fieldEditor class='rose-autosize' @options={{this.hclCodeEditor}} />
|
||||
</Rose::CodeEditor>
|
||||
<p>{{t 'resources.worker.form.steps.1.save_config'}}</p>
|
||||
<Hds::CodeBlock
|
||||
@language='bash'
|
||||
@value={{this.createConfigText}}
|
||||
@hasCopyButton={{true}}
|
||||
@hasLineNumbers={{false}}
|
||||
/>
|
||||
|
||||
<p>
|
||||
{{t 'resources.worker.form.steps.1.create_config'}}
|
||||
</p>
|
||||
|
||||
<Hds::CodeBlock
|
||||
@language='hcl'
|
||||
@value={{this.workerConfigText}}
|
||||
@hasCopyButton={{true}}
|
||||
@hasLineNumbers={{false}}
|
||||
/>
|
||||
|
||||
<p>
|
||||
{{t 'resources.worker.form.steps.1.save_config' htmlSafe=true}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3>{{t 'resources.worker.form.steps.2.title'}}</h3>
|
||||
<div class='worker-create-section'>
|
||||
<Rose::CodeEditor @codeValue={{this.installBoundaryText}} as |c|>
|
||||
<c.toolbar>
|
||||
<:action>
|
||||
<span>{{t 'resources.worker.form.steps.2.run_command'}}</span>
|
||||
</:action>
|
||||
</c.toolbar>
|
||||
<c.fieldEditor class='rose-autosize' @options={{this.shellCodeEditor}} />
|
||||
</Rose::CodeEditor>
|
||||
<span>{{t 'resources.worker.form.steps.2.copy_registration_request'}}</span>
|
||||
<code>{{t
|
||||
'resources.worker.form.steps.3.worker_auth_registration_request.label'
|
||||
}}
|
||||
</code>
|
||||
|
||||
<p>
|
||||
{{t 'resources.worker.form.steps.2.run_command'}}
|
||||
</p>
|
||||
|
||||
<Hds::CodeBlock
|
||||
@language='bash'
|
||||
@value={{this.installBoundaryText}}
|
||||
@hasCopyButton={{true}}
|
||||
@hasLineNumbers={{false}}
|
||||
/>
|
||||
|
||||
<p>
|
||||
{{t 'resources.worker.form.steps.2.copy_registration_request'}}
|
||||
<code>{{t
|
||||
'resources.worker.form.steps.3.worker_auth_registration_request.label'
|
||||
}}</code>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3>{{t 'resources.worker.form.steps.3.title'}}</h3>
|
||||
<div class='worker-create-section'>
|
||||
<div class='worker-auth-token'>
|
||||
<form.input
|
||||
@name='worker_auth_registration_request'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='worker_auth_registration_request'
|
||||
@value={{this.generatedWorkerAuthToken}}
|
||||
@disabled={{@model.cannotSave}}
|
||||
@label={{t
|
||||
'resources.worker.form.steps.3.worker_auth_registration_request.label'
|
||||
}}
|
||||
@helperText={{t
|
||||
'resources.worker.form.steps.3.worker_auth_registration_request.help'
|
||||
}}
|
||||
/>
|
||||
@isRequired={{true}}
|
||||
@isInvalid={{@model.errors.worker_generated_auth_token}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event this 'generatedWorkerAuthToken')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t
|
||||
'resources.worker.form.steps.3.worker_auth_registration_request.label'
|
||||
}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t
|
||||
'resources.worker.form.steps.3.worker_auth_registration_request.help'
|
||||
}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.worker_generated_auth_token}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.worker_generated_auth_token as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{#if (can 'save worker' @model)}}
|
||||
<Rose::Button
|
||||
@onSubmit={{true}}
|
||||
@style='primary'
|
||||
<Hds::Button
|
||||
@text={{t 'resources.worker.actions.register'}}
|
||||
type='submit'
|
||||
disabled={{@model.cannotSave}}
|
||||
class='nowrap'
|
||||
@disabled={{@model.cannotSave}}
|
||||
>
|
||||
{{t 'resources.worker.actions.register'}}
|
||||
</Rose::Button>
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,39 +11,31 @@
|
||||
as |form|
|
||||
>
|
||||
|
||||
<form.input
|
||||
@name='type'
|
||||
@value={{@model.type}}
|
||||
@label={{t 'form.type.label'}}
|
||||
@helperText={{t 'form.worker_type.help'}}
|
||||
@disabled={{true}}
|
||||
readonly={{true}}
|
||||
/>
|
||||
|
||||
<form.input
|
||||
@name='name'
|
||||
@type='name'
|
||||
<Hds::Form::TextInput::Field
|
||||
name='name'
|
||||
@value={{@model.name}}
|
||||
@label={{t 'form.name.label'}}
|
||||
@helperText={{t 'form.name.help'}}
|
||||
@error={{@model.errors.name}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
@isInvalid={{@model.errors.name}}
|
||||
@isOptional={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<field.errors as |errors|>
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
<E.Message data-test-error-message-name>{{error.message}}</E.Message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='description'
|
||||
@isOptional={{true}}
|
||||
@value={{@model.description}}
|
||||
@isInvalid={{@model.errors.description}}
|
||||
name='description'
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
@@ -82,42 +74,34 @@
|
||||
</F.Control>
|
||||
</Hds::Form::Fieldset>
|
||||
|
||||
<form.input
|
||||
@name='address'
|
||||
@type='url'
|
||||
@value={{@model.address}}
|
||||
@label={{t 'form.address.label'}}
|
||||
@helperText={{t 'form.worker_address.help'}}
|
||||
@disabled={{true}}
|
||||
readonly={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.address}} disabled={{form.disabled}} as |F|>
|
||||
<F.Label>{{t 'form.address.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.worker_address.help'}}</F.HelperText>
|
||||
</InfoField>
|
||||
|
||||
{{#let
|
||||
(relative-datetime-live @model.last_status_time)
|
||||
(format-date @model.last_status_time format='yymmddt')
|
||||
as |relativeDate customFormat|
|
||||
}}
|
||||
<form.input
|
||||
@name='last seen'
|
||||
@type='datetime'
|
||||
<InfoField
|
||||
@value={{if
|
||||
@model.last_status_time
|
||||
(concat relativeDate ', ' customFormat)
|
||||
}}
|
||||
@label={{t 'form.worker_last_seen.label'}}
|
||||
@helperText={{t 'form.worker_last_seen.help'}}
|
||||
@disabled={{true}}
|
||||
readonly={{true}}
|
||||
/>
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.worker_last_seen.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.worker_last_seen.help'}}</F.HelperText>
|
||||
</InfoField>
|
||||
|
||||
{{/let}}
|
||||
|
||||
<form.input
|
||||
@name='release version'
|
||||
@value={{@model.release_version}}
|
||||
@label={{t 'form.worker_release_version.label'}}
|
||||
@helperText={{t 'form.worker_release_version.help'}}
|
||||
@disabled={{true}}
|
||||
readonly={{true}}
|
||||
/>
|
||||
<InfoField @value={{@model.release_version}} readonly={{true}} as |F|>
|
||||
<F.Label>{{t 'form.worker_release_version.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.worker_release_version.help'}}</F.HelperText>
|
||||
</InfoField>
|
||||
|
||||
{{#if (can 'save worker' @model)}}
|
||||
<form.actions
|
||||
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='group' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.group.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='host-catalog' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.host-catalog.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
+1
-7
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='host-set' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.host-set.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
+1
-7
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='host' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.host.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='host' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.host.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='role' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.role.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='target' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.target.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -8,10 +8,4 @@
|
||||
<DocLink @doc='user' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.user.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { hash } from 'rsvp';
|
||||
|
||||
export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
// =services
|
||||
@@ -13,6 +12,7 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
@service session;
|
||||
@service router;
|
||||
@service resourceFilterStore;
|
||||
|
||||
// =methods
|
||||
|
||||
beforeModel() {
|
||||
@@ -27,16 +27,7 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
*/
|
||||
async model() {
|
||||
const { id: scope_id } = this.modelFor('scopes.scope');
|
||||
// Fetch auth methods for the current scope
|
||||
const authMethods = await this.resourceFilterStore.queryBy(
|
||||
'auth-method',
|
||||
{
|
||||
authorized_actions: [{ contains: 'authenticate' }],
|
||||
},
|
||||
{
|
||||
scope_id,
|
||||
},
|
||||
);
|
||||
|
||||
// Preload all authenticatable auth methods into the store
|
||||
const authMethodsForAllScopes = await this.resourceFilterStore.queryBy(
|
||||
'auth-method',
|
||||
@@ -48,22 +39,25 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
recursive: true,
|
||||
},
|
||||
);
|
||||
// Fetch org scopes
|
||||
// and filter out any that have no auth methods
|
||||
const scopes = this.modelFor('scopes').filter(
|
||||
({ id: scope_id, isOrg }) =>
|
||||
isOrg &&
|
||||
authMethodsForAllScopes.filter((i) => i.scopeID === scope_id).length,
|
||||
|
||||
const scopeIDs = new Set(
|
||||
authMethodsForAllScopes.map((authMethod) => authMethod.scopeID),
|
||||
);
|
||||
return hash({
|
||||
|
||||
// Fetch org scopes and filter out any that have no auth methods
|
||||
const scopes = this.modelFor('scopes').filter(({ id: scope_id }) =>
|
||||
scopeIDs.has(scope_id),
|
||||
);
|
||||
|
||||
// Filter out auth methods that are not for the current scope
|
||||
const authMethods = authMethodsForAllScopes.filter(
|
||||
(authMethod) => authMethod.scopeID === scope_id,
|
||||
);
|
||||
|
||||
return {
|
||||
scope: this.modelFor('scopes.scope'),
|
||||
scopes,
|
||||
authMethods,
|
||||
// for integration testing:
|
||||
// authMethods: A([{
|
||||
// id: 'am_1234567890',
|
||||
// type: 'password'
|
||||
// }])
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { loading } from 'ember-loading';
|
||||
import { confirm } from 'core/decorators/confirm';
|
||||
import { action } from '@ember/object';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
|
||||
export default class ScopesScopeSessionRecordingsRoute extends Route {
|
||||
// =services
|
||||
@@ -68,4 +72,19 @@ export default class ScopesScopeSessionRecordingsRoute extends Route {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the session recording
|
||||
* @param {SessionRecording} recording
|
||||
*/
|
||||
@action
|
||||
@loading
|
||||
@confirm('resources.session-recording.questions.delete')
|
||||
@notifyError(({ message }) => message, { catch: true })
|
||||
@notifySuccess('notifications.delete-success')
|
||||
async delete(recording) {
|
||||
await recording.destroyRecord();
|
||||
await this.router.replaceWith('scopes.scope.session-recordings');
|
||||
this.router.refresh();
|
||||
}
|
||||
}
|
||||
@@ -174,33 +174,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.copyable {
|
||||
white-space: nowrap;
|
||||
|
||||
.copyable-button {
|
||||
margin: 0;
|
||||
padding: 0 sizing.rems(xxs);
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
mark {
|
||||
animation: fade-background 0.75s linear;
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
|
||||
@keyframes fade-background {
|
||||
0% {
|
||||
background-color: var(--action-subtler-1);
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[class*='session-status-'] {
|
||||
color: var(--ui-gray-subtler-2);
|
||||
}
|
||||
@@ -284,29 +257,7 @@
|
||||
}
|
||||
|
||||
.create-resources-item-controller-copyable {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
|
||||
border-radius: sizing.rems(xxxs);
|
||||
color: var(--action);
|
||||
height: (sizing.rems(xs) * 5);
|
||||
margin: sizing.rems(xxs) 0 sizing.rems(l) 0;
|
||||
|
||||
.copyable {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: sizing.rems(s);
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.copyable-button {
|
||||
top: 0; // This is to override a negative top declared above
|
||||
}
|
||||
}
|
||||
|
||||
.image-container > svg {
|
||||
@@ -337,16 +288,21 @@
|
||||
margin-bottom: sizing.rems(l);
|
||||
}
|
||||
|
||||
> code {
|
||||
background-color: var(--ui-gray-subtler-5);
|
||||
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
|
||||
color: var(--failure);
|
||||
> p code {
|
||||
background-color: var(--token-color-surface-strong);
|
||||
border-radius: 5px;
|
||||
color: var(--token-color-foreground-primary);
|
||||
padding: sizing.rems(xxxs) sizing.rems(xxs);
|
||||
}
|
||||
|
||||
.worker-auth-token {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
gap: sizing.rems(m);
|
||||
|
||||
[class*='hds-form-field--layout'] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.worker-success {
|
||||
|
||||
@@ -10,13 +10,7 @@
|
||||
<Rose::Notification @style='error' @heading={{t 'auth.titles.flow-error'}}>
|
||||
{{t 'auth.descriptions.flow-error'}}
|
||||
<br />
|
||||
<Copyable
|
||||
@text={{@model}}
|
||||
@buttonText={{t 'actions.copy-error-detail-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
{{t 'actions.copy-error-detail-to-clipboard'}}
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model}} @color='secondary' />
|
||||
</Rose::Notification>
|
||||
</Rose::Layout::Centered>
|
||||
</main>
|
||||
@@ -54,13 +54,7 @@
|
||||
'onboarding.success.descriptions.controller'
|
||||
}}</span>
|
||||
<div class='create-resources-item-controller-copyable'>
|
||||
<Copyable
|
||||
@text={{this.model.clusterUrl}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{this.model.clusterUrl}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{this.model.clusterUrl}} />
|
||||
</div>
|
||||
|
||||
<Image @name='targets' />
|
||||
|
||||
+1
-7
@@ -18,13 +18,7 @@
|
||||
<page.header>
|
||||
<h2>{{t 'resources.account.title'}}</h2>
|
||||
<p>{{t 'resources.account.messages.set-password.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.navigation>
|
||||
|
||||
@@ -69,13 +69,10 @@
|
||||
<Hds::Badge @text={{B.data.type}} />
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
@@ -154,13 +151,10 @@
|
||||
<Hds::Badge @text={{B.data.type}} />
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
|
||||
+8
-14
@@ -51,13 +51,10 @@
|
||||
<B.Td>{{B.data.description}}</B.Td>
|
||||
<B.Td><Hds::Badge @text={{B.data.type}} /></B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
@@ -91,13 +88,10 @@
|
||||
<B.Td>{{B.data.description}}</B.Td>
|
||||
<B.Td><Hds::Badge @text={{B.data.type}} /></B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
{{truncate-list 'actions.more' B.data.group_names 3}}
|
||||
|
||||
+4
-7
@@ -61,13 +61,10 @@
|
||||
<B.Td>{{B.data.full_name}}</B.Td>
|
||||
<B.Td><Hds::Badge @text={{B.data.type}} /></B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
|
||||
@@ -146,13 +146,10 @@
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
{{#if B.data.isPrimary}}
|
||||
|
||||
@@ -61,6 +61,19 @@
|
||||
{{#if @model.authMethods}}
|
||||
{{outlet}}
|
||||
{{/if}}
|
||||
{{#unless @model.authMethods}}
|
||||
<Rose::Layout::Centered>
|
||||
<Rose::Message
|
||||
@title={{t 'resources.auth-method.messages.none.title'}}
|
||||
@icon='flight-icons/svg/alert-circle-16'
|
||||
as |message|
|
||||
>
|
||||
<message.description>
|
||||
{{t 'resources.auth-method.messages.none.description'}}
|
||||
</message.description>
|
||||
</Rose::Message>
|
||||
</Rose::Layout::Centered>
|
||||
{{/unless}}
|
||||
</:body>
|
||||
</Rose::Frame>
|
||||
</page.body>
|
||||
|
||||
+1
-7
@@ -15,13 +15,7 @@
|
||||
<DocLink @doc='credential-library' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.credential-library.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.navigation>
|
||||
|
||||
+1
-7
@@ -15,13 +15,7 @@
|
||||
<DocLink @doc='credential' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.credential.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.navigation>
|
||||
|
||||
@@ -41,13 +41,7 @@
|
||||
</h2>
|
||||
<p>{{t 'resources.project.description'}}</p>
|
||||
{{/if}}
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
{{#if (can 'read model' @model)}}
|
||||
@@ -178,7 +172,7 @@
|
||||
/>
|
||||
<dd.Separator />
|
||||
<dd.Interactive
|
||||
@text={{t 'resources.policy.actions.delete'}}
|
||||
@text={{t 'resources.policy.actions.detach'}}
|
||||
@color='critical'
|
||||
{{on
|
||||
'click'
|
||||
|
||||
@@ -54,13 +54,10 @@
|
||||
</span>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<ScopeBadge @scope={{B.data.scopeModel}} />
|
||||
|
||||
@@ -52,13 +52,10 @@
|
||||
<p>{{B.data.description}}</p>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
|
||||
@@ -52,13 +52,10 @@
|
||||
<HostCatalogTypeBadge @model={{B.data}} />
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<Hds::Text::Code>{{B.data.id}}</Hds::Text::Code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Hds::Text::Code>{{B.data.address}}</Hds::Text::Code>
|
||||
|
||||
@@ -54,13 +54,10 @@
|
||||
<p>{{B.data.description}}</p>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
|
||||
@@ -21,13 +21,7 @@
|
||||
<DocLink @doc='role' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.role.grant.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.actions>
|
||||
|
||||
@@ -21,13 +21,7 @@
|
||||
<DocLink @doc='role' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.role.principal.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.role.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.role.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.role.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.actions>
|
||||
@@ -65,13 +59,10 @@
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<PrincipalTypeBadge @model={{B.data}} />
|
||||
|
||||
+12
-21
@@ -26,13 +26,10 @@
|
||||
@model.channelRecording
|
||||
}}
|
||||
</h2>
|
||||
<Copyable
|
||||
@text={{@model.channelRecording.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.channelRecording.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.channelRecording.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</page.header>
|
||||
|
||||
<page.body>
|
||||
@@ -142,13 +139,10 @@
|
||||
@color='boundary'
|
||||
@text={{t 'resources.session-recording.title'}}
|
||||
>
|
||||
<Copyable
|
||||
@text={{@model.sessionRecording.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.sessionRecording.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.sessionRecording.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
{{! Connection Recording ID }}
|
||||
<list.Item
|
||||
@@ -156,13 +150,10 @@
|
||||
@color='boundary'
|
||||
@text={{t 'resources.session-recording.connection.title'}}
|
||||
>
|
||||
<Copyable
|
||||
@text={{@model.channelRecording.connection_recording.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.channelRecording.connection_recording.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.channelRecording.connection_recording.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
</LinkListPanel>
|
||||
</div>
|
||||
|
||||
+27
-23
@@ -16,8 +16,12 @@
|
||||
{{#if
|
||||
(can 'reapplyStoragePolicy session-recording' @model.sessionRecording)
|
||||
}}
|
||||
<Hds::Dropdown data-test-manage-dropdown as |dd|>
|
||||
<dd.ToggleButton @text={{t 'actions.manage'}} @color='secondary' />
|
||||
<Hds::Dropdown as |dd|>
|
||||
<dd.ToggleButton
|
||||
data-test-manage-dropdown
|
||||
@text={{t 'actions.manage'}}
|
||||
@color='secondary'
|
||||
/>
|
||||
|
||||
<dd.Interactive
|
||||
@text={{t 'resources.policy.actions.update'}}
|
||||
@@ -26,6 +30,15 @@
|
||||
(route-action 'reapplyStoragepolicy' @model.sessionRecording)
|
||||
}}
|
||||
/>
|
||||
{{#if (can 'delete session-recording' @model.sessionRecording)}}
|
||||
<dd.Separator />
|
||||
<dd.Interactive
|
||||
data-test-manage-dropdown-delete
|
||||
@color='critical'
|
||||
@text={{t 'resources.policy.actions.delete_recording'}}
|
||||
{{on 'click' (route-action 'delete' @model.sessionRecording)}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Hds::Dropdown>
|
||||
{{/if}}
|
||||
</page.actions>
|
||||
@@ -75,13 +88,10 @@
|
||||
connection
|
||||
}}
|
||||
</p>
|
||||
<Copyable
|
||||
@text={{connection.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{connection.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{connection.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</div>
|
||||
{{#if connection.channel_recordings}}
|
||||
<Hds::Table
|
||||
@@ -143,13 +153,10 @@
|
||||
</Rose::MetadataList>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td align='right'>
|
||||
{{#if (can 'play channel-recording' B.data)}}
|
||||
@@ -337,13 +344,10 @@
|
||||
@color='boundary'
|
||||
@text={{t 'resources.session-recording.title'}}
|
||||
>
|
||||
<Copyable
|
||||
@text={{@model.sessionRecording.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.sessionRecording.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.sessionRecording.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
</LinkListPanel>
|
||||
</div>
|
||||
|
||||
@@ -90,13 +90,10 @@
|
||||
@name='flight-icons/svg/entry-point-16'
|
||||
@size='medium'
|
||||
/>
|
||||
<Copyable
|
||||
@text={{B.data.session.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<Hds::Text::Code>{{B.data.session.id}}</Hds::Text::Code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.session.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Hds::Text::Code>{{B.data.user.id}}</Hds::Text::Code>
|
||||
|
||||
@@ -58,13 +58,10 @@
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
{{#if B.data.isAWS}}
|
||||
|
||||
@@ -13,13 +13,7 @@
|
||||
{{t 'resources.storage-bucket.title'}}
|
||||
<DocLink @doc='storage-bucket' @iconSize='large' />
|
||||
</h2>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.navigation>
|
||||
|
||||
@@ -66,13 +66,10 @@
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
{{else}}
|
||||
@@ -99,13 +96,10 @@
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
{{/if}}
|
||||
|
||||
@@ -69,13 +69,10 @@
|
||||
<CredSourceTypeBadge @model={{B.data}} />
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
{{#if (can 'removeCredentialSources target' @model)}}
|
||||
|
||||
@@ -59,13 +59,10 @@
|
||||
<HostCatalogTypeBadge @model={{B.data.model}} />
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.model.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
{{#if (can 'removeHostSources target' @model)}}
|
||||
|
||||
+4
-7
@@ -73,13 +73,10 @@
|
||||
<CredSourceTypeBadge @model={{B.data}} />
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
{{#if (can 'removeCredentialSources target' @model)}}
|
||||
|
||||
@@ -57,13 +57,10 @@
|
||||
<p>{{B.data.description}}</p>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
|
||||
@@ -60,13 +60,10 @@
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
|
||||
|
||||
@@ -136,13 +136,10 @@
|
||||
<B.Td>{{B.data.release_version}}</B.Td>
|
||||
<B.Td>{{B.data.address}} </B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
|
||||
@@ -15,13 +15,7 @@
|
||||
<DocLink @doc='worker' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.worker.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{@model.id}}</code>
|
||||
</Copyable>
|
||||
<Hds::Copy::Snippet @textToCopy={{@model.id}} @color='secondary' />
|
||||
</page.header>
|
||||
|
||||
<page.navigation>
|
||||
|
||||
@@ -39,13 +39,6 @@ module.exports = function (defaults) {
|
||||
},
|
||||
});
|
||||
|
||||
// Only import when in development or test mode
|
||||
if (app.env.match(/(development)|(test)/i)) {
|
||||
app.import('node_modules/clipboard/dist/clipboard.js');
|
||||
} else {
|
||||
app.import('node_modules/clipboard/dist/clipboard.min.js');
|
||||
}
|
||||
|
||||
// Use `app.import` to add additional libraries to the generated
|
||||
// output files.
|
||||
//
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
"@playwright/test": "^1.30.0",
|
||||
"babel-loader": "^8.2.5",
|
||||
"broccoli-asset-rev": "^3.0.0",
|
||||
"clipboard": "^2.0.8",
|
||||
"concurrently": "^8.0.1",
|
||||
"core": "*",
|
||||
"doctoc": "^2.2.0",
|
||||
|
||||
@@ -118,7 +118,7 @@ module('Acceptance | auth-methods | create', function (hooks) {
|
||||
await fillIn('[name="client_id"]', 'client_id');
|
||||
await fillIn('[name="client_secret"]', 'client_secret');
|
||||
await select('form fieldset:nth-of-type(1) select', 'RS384');
|
||||
await click('form fieldset:nth-of-type(1) [title="Add"]');
|
||||
await click('[data-test-add-option-button]');
|
||||
await fillIn(ALLOWED_AUDIENCES_INPUT_SELECTOR, 'allowed_audiences');
|
||||
await click(ALLOWED_AUDIENCES_BTN_SELECTOR, 'allowed_audiences');
|
||||
await fillIn(CLAIMS_SCOPES_INPUT_SELECTOR, 'claims_scopes');
|
||||
|
||||
@@ -53,6 +53,12 @@ module('Acceptance | auth-methods | update', function (hooks) {
|
||||
const CLAIMS_SCOPES_INPUT_SELECTOR = '[name="claims_scopes"] input';
|
||||
const TOGGLE_SELECTOR = '[name="prompts"]';
|
||||
|
||||
const SIGNING_ALGORITHMS_REMOVE_BTN_SELECTOR =
|
||||
'[data-test-remove-option-button]';
|
||||
const SIGNING_ALGORITHMS_INPUT_SELECTOR =
|
||||
'.list-wrapper-field tbody tr:last-child select';
|
||||
const SIGNING_ALGORITHMS_ADD_BTN_SELECTOR = '[data-test-add-option-button]';
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
@@ -123,14 +129,16 @@ module('Acceptance | auth-methods | update', function (hooks) {
|
||||
await fillIn('[name="issuer"]', 'issuer');
|
||||
await fillIn('[name="client_id"]', 'client_id');
|
||||
await fillIn('[name="client_secret"]', 'client_secret');
|
||||
|
||||
// Remove all signing algorithms
|
||||
await Promise.all(
|
||||
findAll('form fieldset:nth-of-type(1) [title="Remove"]').map((element) =>
|
||||
click(element),
|
||||
),
|
||||
);
|
||||
await select('form fieldset:nth-of-type(1) select', 'RS384');
|
||||
await click('form fieldset:nth-of-type(1) [title="Add"]');
|
||||
let removeButtons = findAll(SIGNING_ALGORITHMS_REMOVE_BTN_SELECTOR);
|
||||
|
||||
for (const element of removeButtons) {
|
||||
await click(element);
|
||||
}
|
||||
await select(SIGNING_ALGORITHMS_INPUT_SELECTOR, 'RS384');
|
||||
await click(SIGNING_ALGORITHMS_ADD_BTN_SELECTOR);
|
||||
|
||||
// Remove all allowed audiences
|
||||
const allowedAudiencesList = findAll(ALLOWED_AUDIENCES_REMOVE_BTN_SELECTOR);
|
||||
|
||||
@@ -347,8 +355,9 @@ module('Acceptance | auth-methods | update', function (hooks) {
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'existing auth method');
|
||||
await click(SAVE_BTN_SELECTOR);
|
||||
await a11yAudit();
|
||||
|
||||
assert.dom(ERROR_MSG_SELECTOR).hasText('The request was invalid.');
|
||||
assert.dom('.rose-form-error-message').hasText('Name is required.');
|
||||
assert.dom('.hds-form-error__message').hasText('Name is required.');
|
||||
});
|
||||
|
||||
test('saving an existing ldap auth method with invalid fields displays error messages', async function (assert) {
|
||||
|
||||
@@ -76,6 +76,15 @@ module('Acceptance | authentication', function (hooks) {
|
||||
},
|
||||
'withChildren',
|
||||
);
|
||||
// create an emtpy org with no auth methods
|
||||
this.server.create(
|
||||
'scope',
|
||||
{
|
||||
type: 'org',
|
||||
scope: { id: globalScope.id, type: globalScope.type },
|
||||
},
|
||||
'withChildren',
|
||||
);
|
||||
scope = { id: orgScope.id, type: orgScope.type };
|
||||
globalAuthMethod = this.server.create('auth-method', {
|
||||
scope: globalScope,
|
||||
@@ -366,4 +375,12 @@ module('Acceptance | authentication', function (hooks) {
|
||||
});
|
||||
|
||||
// TODO: test OIDC retry and cancel
|
||||
|
||||
test('org scopes with no auth methods are not visible in dropdown', async function (assert) {
|
||||
await visit(authMethodGlobalAuthenticateURL);
|
||||
|
||||
await click('.rose-dropdown-trigger');
|
||||
|
||||
assert.dom('.rose-dropdown-content a').exists({ count: 2 });
|
||||
});
|
||||
});
|
||||
@@ -88,12 +88,34 @@ module('Acceptance | credential-libraries | create', function (hooks) {
|
||||
assert.strictEqual(currentURL(), urls.credentialLibrary);
|
||||
});
|
||||
|
||||
test('can create a credential library', async function (assert) {
|
||||
test('can create a new credential library of type vault generic', async function (assert) {
|
||||
const count = getCredentialLibraryCount();
|
||||
await visit(urls.newCredentialLibrary);
|
||||
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await select('[name="credential_type"]', 'ssh_private_key');
|
||||
|
||||
await select(
|
||||
'[name="credential_mapping_overrides"] tbody td:nth-of-type(1) select',
|
||||
'private_key_attribute',
|
||||
);
|
||||
await fillIn(
|
||||
'[name="credential_mapping_overrides"] tbody td:nth-of-type(2) input',
|
||||
'key',
|
||||
);
|
||||
await click('[name="credential_mapping_overrides"] button');
|
||||
|
||||
await click('[type="submit"]');
|
||||
assert.strictEqual(getCredentialLibraryCount(), count + 1);
|
||||
|
||||
const credentialLibrary = this.server.schema.credentialLibraries.findBy({
|
||||
name: 'random string',
|
||||
});
|
||||
assert.strictEqual(credentialLibrary.name, 'random string');
|
||||
assert.strictEqual(credentialLibrary.credentialType, 'ssh_private_key');
|
||||
assert.deepEqual(credentialLibrary.credentialMappingOverrides, {
|
||||
private_key_attribute: 'key',
|
||||
});
|
||||
});
|
||||
|
||||
test('can create a new credential library of type vault ssh cert', async function (assert) {
|
||||
|
||||
@@ -22,6 +22,17 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
|
||||
const BUTTON_SELECTOR = '.rose-form-actions [type="button"]';
|
||||
const SAVE_BTN_SELECTOR = '.rose-form-actions [type="submit"]';
|
||||
const NAME_INPUT_SELECTOR = '[name="name"]';
|
||||
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
|
||||
const DESC_INPUT_SELECTOR = '[name="description"]';
|
||||
const VAULT_PATH_SELECTOR = '[name="vault_path"]';
|
||||
const CRED_TYPE_SELECTOR = '[name="credential_type"]';
|
||||
const CRED_MAPPING_OVERRIDES_SELECT =
|
||||
'[name="credential_mapping_overrides"] tbody td:nth-of-type(1) select';
|
||||
const CRED_MAPPING_OVERRIDES_INPUT =
|
||||
'[name="credential_mapping_overrides"] tbody td:nth-of-type(2) input';
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
@@ -73,43 +84,58 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
authenticateSession({});
|
||||
});
|
||||
|
||||
test('can update resource and save changes', async function (assert) {
|
||||
assert.notEqual(instances.credentialLibrary.name, 'random string');
|
||||
await visit(urls.credentialLibrary);
|
||||
await click('form [type="button"]', 'Activate edit mode');
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('.rose-form-actions [type="submit"]');
|
||||
assert.strictEqual(currentURL(), urls.credentialLibrary);
|
||||
assert.strictEqual(
|
||||
this.server.schema.credentialLibraries.all().models[0].name,
|
||||
'random string',
|
||||
);
|
||||
});
|
||||
|
||||
test('cannot update resource without proper authorization', async function (assert) {
|
||||
instances.credentialLibrary.authorized_actions =
|
||||
instances.credentialLibrary.authorized_actions.filter(
|
||||
(item) => item !== 'update',
|
||||
);
|
||||
await visit(urls.credentialLibrary);
|
||||
assert.notOk(find('form [type="button"]'));
|
||||
assert.notOk(find(BUTTON_SELECTOR));
|
||||
});
|
||||
|
||||
test('can update a credential library and cancel changes', async function (assert) {
|
||||
await visit(urls.credentialLibrary);
|
||||
await click('form [type="button"]', 'Activate edit mode');
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('.rose-form-actions [type="button"]');
|
||||
await click(BUTTON_SELECTOR, 'Activate edit mode');
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'random string');
|
||||
await click(BUTTON_SELECTOR);
|
||||
assert.notEqual(
|
||||
this.server.schema.credentialLibraries.all().models[0].name,
|
||||
'random string',
|
||||
);
|
||||
assert.strictEqual(
|
||||
find('[name="name"]').value,
|
||||
find(NAME_INPUT_SELECTOR).value,
|
||||
instances.credentialLibrary.name,
|
||||
);
|
||||
});
|
||||
|
||||
test('can update a vault generic credential library and save changes', async function (assert) {
|
||||
await visit(
|
||||
`${urls.credentialLibraries}/${instances.credentialLibrary.id}`,
|
||||
);
|
||||
|
||||
await click(BUTTON_SELECTOR);
|
||||
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'random string');
|
||||
await fillIn(DESC_INPUT_SELECTOR, 'description');
|
||||
await fillIn(VAULT_PATH_SELECTOR, 'path');
|
||||
|
||||
await select(CRED_MAPPING_OVERRIDES_SELECT, 'private_key_attribute');
|
||||
await fillIn(CRED_MAPPING_OVERRIDES_INPUT, 'key');
|
||||
|
||||
await click('[name="credential_mapping_overrides"] button');
|
||||
|
||||
await click(SAVE_BTN_SELECTOR);
|
||||
const credentialLibrary = this.server.schema.credentialLibraries.findBy({
|
||||
name: 'random string',
|
||||
});
|
||||
assert.strictEqual(credentialLibrary.name, 'random string');
|
||||
assert.strictEqual(credentialLibrary.description, 'description');
|
||||
assert.strictEqual(credentialLibrary.attributes.path, 'path');
|
||||
assert.deepEqual(credentialLibrary.credentialMappingOverrides, {
|
||||
private_key_attribute: 'key',
|
||||
});
|
||||
});
|
||||
|
||||
test('saving an existing credential library with invalid fields displays error messages', async function (assert) {
|
||||
this.server.patch('/credential-libraries/:id', () => {
|
||||
return new Response(
|
||||
@@ -131,15 +157,15 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
);
|
||||
});
|
||||
await visit(urls.credentialLibrary);
|
||||
await click('form [type="button"]', 'Activate edit mode');
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('[type="submit"]');
|
||||
await click(BUTTON_SELECTOR, 'Activate edit mode');
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'random string');
|
||||
await click(SAVE_BTN_SELECTOR);
|
||||
assert.ok(
|
||||
find('[role="alert"]').textContent.trim(),
|
||||
'The request was invalid.',
|
||||
);
|
||||
assert.ok(
|
||||
find('.hds-form-error__message').textContent.trim(),
|
||||
find(FIELD_ERROR_TEXT_SELECTOR).textContent.trim(),
|
||||
'Name is required.',
|
||||
);
|
||||
});
|
||||
@@ -151,8 +177,8 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
assert.notEqual(instances.credentialLibrary.name, 'random string');
|
||||
|
||||
await visit(urls.credentialLibrary);
|
||||
await click('form [type="button"]', 'Activate edit mode');
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click(BUTTON_SELECTOR, 'Activate edit mode');
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'random string');
|
||||
assert.strictEqual(currentURL(), urls.credentialLibrary);
|
||||
|
||||
try {
|
||||
@@ -174,8 +200,8 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
confirmService.enabled = true;
|
||||
assert.notEqual(instances.credentialLibrary.name, 'random string');
|
||||
await visit(urls.credentialLibrary);
|
||||
await click('form [type="button"]', 'Activate edit mode');
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click(BUTTON_SELECTOR, 'Activate edit mode');
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'random string');
|
||||
assert.strictEqual(currentURL(), urls.credentialLibrary);
|
||||
|
||||
try {
|
||||
@@ -191,6 +217,12 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
}
|
||||
});
|
||||
|
||||
test('cannot update credential type in a vault generic credential library', async function (assert) {
|
||||
await visit(urls.credentialLibrary);
|
||||
await click(BUTTON_SELECTOR, 'Activate edit mode');
|
||||
assert.dom(CRED_TYPE_SELECTOR).isDisabled();
|
||||
});
|
||||
|
||||
test('can update a vault ssh cert credential library and save changes', async function (assert) {
|
||||
instances.credentialLibrary = this.server.create('credential-library', {
|
||||
scope: instances.scopes.project,
|
||||
@@ -200,10 +232,10 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
await visit(
|
||||
`${urls.credentialLibraries}/${instances.credentialLibrary.id}`,
|
||||
);
|
||||
await click('form [type="button"]:not(:disabled)', 'Activate edit mode');
|
||||
await fillIn('[name="name"]', 'name');
|
||||
await fillIn('[name="description"]', 'description');
|
||||
await fillIn('[name="vault_path"]', 'path');
|
||||
await click(BUTTON_SELECTOR, 'Activate edit mode');
|
||||
await fillIn(NAME_INPUT_SELECTOR, 'name');
|
||||
await fillIn(DESC_INPUT_SELECTOR, 'description');
|
||||
await fillIn(VAULT_PATH_SELECTOR, 'path');
|
||||
await fillIn('[name="username"]', 'username');
|
||||
await select('[name="key_type"]', 'rsa');
|
||||
await fillIn('[name="key_bits"]', 100);
|
||||
@@ -226,8 +258,10 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
'[name="extensions"] tbody td:nth-of-type(2) input',
|
||||
'ext_value',
|
||||
);
|
||||
|
||||
await click('[name="extensions"] button');
|
||||
await click('[type="submit"]');
|
||||
|
||||
await click(SAVE_BTN_SELECTOR);
|
||||
const credentialLibrary = this.server.schema.credentialLibraries.findBy({
|
||||
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
||||
});
|
||||
|
||||
@@ -134,7 +134,7 @@ module('Acceptance | credential-stores | create', function (hooks) {
|
||||
'The request was invalid.',
|
||||
);
|
||||
assert.ok(
|
||||
find('.rose-form-error-message').textContent.trim(),
|
||||
find('[data-test-error-message-name]').textContent.trim(),
|
||||
'Name is required.',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -235,7 +235,7 @@ module(
|
||||
.dom('.rose-notification-body')
|
||||
.hasText('Error in provided request.');
|
||||
assert
|
||||
.dom('.rose-form-error-message')
|
||||
.dom('[data-test-error-message-password]')
|
||||
.hasText('Field required for creating a username-password credential.');
|
||||
});
|
||||
|
||||
@@ -270,7 +270,7 @@ module(
|
||||
.dom('.rose-notification-body')
|
||||
.hasText('Error in provided request.');
|
||||
assert
|
||||
.dom('.hds-form-error__message')
|
||||
.dom('[data-test-error-message-private-key]')
|
||||
.hasText('Field required for creating a username-key-pair credential.');
|
||||
});
|
||||
|
||||
|
||||
Loaded 100 of 151 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user