diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 46f93a131..035a8e4ae 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -304,11 +304,15 @@ target: add-brokered-credential-sources: Add Brokered Credentials add-injected-application-credential-sources: Add Injected Application Credentials types: - tcp: TCP + tcp: Generic TCP ssh: SSH help: - tcp: Connections are made over TCP to support a broad range of protocols, including SSH, RDP, databases, and more. This is the most general-purpose type. - ssh: Protocol-aware connections are made over SSH. Use when requiring SSH connections to remote hosts. + tcp: Generic TCP supports a broad range of connection types. + ssh: Protocol-aware SSH with support for credential injection. + form: + type: + label: Type + help: Target type is the protocol with which end users should connect to this target. Choose Generic TCP for broad support of common protocols including RDP, K8s, many databases, and more. host-source: title: Host Source title_plural: Host Sources diff --git a/addons/rose/addon/modifiers/code-mirror.js b/addons/rose/addon/modifiers/code-mirror.js index 077d98d25..3a0e66aab 100644 --- a/addons/rose/addon/modifiers/code-mirror.js +++ b/addons/rose/addon/modifiers/code-mirror.js @@ -9,8 +9,8 @@ import 'codemirror/addon/edit/matchbrackets'; import 'codemirror/addon/edit/closebrackets'; import 'codemirror/addon/selection/active-line'; import 'codemirror/addon/display/autorefresh'; -import 'codemirror/addon/lint/lint' -import 'codemirror/addon/lint/json-lint' +import 'codemirror/addon/lint/lint'; +import 'codemirror/addon/lint/json-lint'; // Here we define default options for the editor. // These should follow the codemirror configuration types diff --git a/ui/admin/app/components/form/target/details/index.hbs b/ui/admin/app/components/form/target/details/index.hbs index 9bdb90a2b..645ba7584 100644 --- a/ui/admin/app/components/form/target/details/index.hbs +++ b/ui/admin/app/components/form/target/details/index.hbs @@ -43,25 +43,25 @@ {{#if (and @model.isNew (feature-flag 'ssh-target'))}} - {{t 'form.type.label'}} - {{#each-in this.mapResourceTypeWithIcon as |targetType icon|}} + {{t 'resources.target.form.type.label'}} + {{t 'resources.target.form.type.help'}} + {{#each this.typeMetas as |type|}} - {{t (concat 'resources.target.types.' targetType)}} + {{t (concat 'resources.target.types.' type.type)}} {{t - (concat 'resources.target.help.' targetType) + (concat 'resources.target.help.' type.type) }} - + - {{/each-in}} + {{/each}} - +
{{else}} {{t 'form.type.label'}} - {{t (concat 'resources.target.help.' @model.type)}} + + {{t (concat 'resources.target.help.' @model.type)}} {{/if}} diff --git a/ui/admin/app/components/form/target/details/index.js b/ui/admin/app/components/form/target/details/index.js index d37de8a08..4085ab018 100644 --- a/ui/admin/app/components/form/target/details/index.js +++ b/ui/admin/app/components/form/target/details/index.js @@ -2,7 +2,10 @@ import Component from '@glimmer/component'; import { types } from 'api/models/target'; //Note: this is a temporary solution till we have resource type helper in place -const icons = ['network', 'terminal']; +const icons = { + ssh: 'terminal-screen', + tcp: 'network', +}; export default class FormTargetComponent extends Component { // =properties @@ -10,8 +13,12 @@ export default class FormTargetComponent extends Component { * maps resource type with icon * @type {object} */ - get mapResourceTypeWithIcon() { - return types.reduce((obj, type, i) => ({ ...obj, [type]: icons[i] }), {}); + get typeMetas() { + const reversedTypes = [...types].reverse(); + return reversedTypes.map((type) => ({ + type, + icon: icons[type], + })); } /** @@ -20,10 +27,6 @@ export default class FormTargetComponent extends Component { * @type {string} */ get icon() { - if (this.args.model.type === 'tcp') { - return icons[0]; - } else { - return icons[1]; - } + return icons[this.args.model.type]; } } diff --git a/ui/admin/app/routes/scopes/scope/targets/new.js b/ui/admin/app/routes/scopes/scope/targets/new.js index 7aae3db3d..7a3f412ef 100644 --- a/ui/admin/app/routes/scopes/scope/targets/new.js +++ b/ui/admin/app/routes/scopes/scope/targets/new.js @@ -7,6 +7,7 @@ export default class ScopesScopeTargetsNewRoute extends Route { @service store; @service router; + @service features; // =methods @@ -23,9 +24,13 @@ export default class ScopesScopeTargetsNewRoute extends Route { * @return {TargetModel} */ - model({ type = 'tcp' }) { - const scopeModel = this.modelFor('scopes.scope'); + model({ type }) { let name, description; + const scopeModel = this.modelFor('scopes.scope'); + + // default type is SSH if the feature is enabled, otherwise TCP + if (!type) type = this.features.isEnabled('ssh-target') ? 'ssh' : 'tcp'; + if (this.currentModel?.isNew) { ({ name, description } = this.currentModel); this.currentModel.rollbackAttributes(); diff --git a/ui/admin/tests/acceptance/targets/create-test.js b/ui/admin/tests/acceptance/targets/create-test.js index 856d33fd2..cfcfb8317 100644 --- a/ui/admin/tests/acceptance/targets/create-test.js +++ b/ui/admin/tests/acceptance/targets/create-test.js @@ -77,25 +77,26 @@ module('Acceptance | targets | create', function (hooks) { authenticateSession({}); }); - test('defaults to a new TCP target when no query param provided', async function (assert) { + test('defaults to type `ssh` when no query param provided', async function (assert) { assert.expect(1); await visit(urls.newTarget); - assert.strictEqual(find('input[name=tcp]:checked').value, 'tcp'); + assert.strictEqual(find('[name="type"]:checked').value, 'ssh'); }); - test('can create new targets of type TCP', async function (assert) { + test('can create type `ssh`', async function (assert) { assert.expect(4); const targetCount = getTargetCount(); - const tcpTargetCount = getTCPTargetCount(); + const sshTargetCount = getSSHTargetCount(); await visit(urls.targets); await click(`[href="${urls.newTarget}"]`); + await click('[value="ssh"]'); await fillIn('[name="name"]', 'random string'); await fillIn('[name="worker_filter"]', 'random filter'); await click('[type="submit"]'); + assert.strictEqual(getSSHTargetCount(), sshTargetCount + 1); assert.strictEqual(getTargetCount(), targetCount + 1); - assert.strictEqual(getTCPTargetCount(), tcpTargetCount + 1); assert.strictEqual( this.server.schema.targets.all().models[getTargetCount() - 1].name, 'random string' @@ -107,20 +108,20 @@ module('Acceptance | targets | create', function (hooks) { ); }); - test('can create new targets of type SSH', async function (assert) { + test('can create type `tcp`', async function (assert) { assert.expect(4); const targetCount = getTargetCount(); - const sshTargetCount = getSSHTargetCount(); + const tcpTargetCount = getTCPTargetCount(); await visit(urls.targets); await click(`[href="${urls.newTarget}"]`); + await click('[value="tcp"]'); await fillIn('[name="name"]', 'random string'); - await click('[value="ssh"]'); await fillIn('[name="worker_filter"]', 'random filter'); await click('[type="submit"]'); - assert.strictEqual(getSSHTargetCount(), sshTargetCount + 1); assert.strictEqual(getTargetCount(), targetCount + 1); + assert.strictEqual(getTCPTargetCount(), tcpTargetCount + 1); assert.strictEqual( this.server.schema.targets.all().models[getTargetCount() - 1].name, 'random string'