Skip to content

Commit

Permalink
Merge pull request #34 from hashicorp/oss/merge-main-0cecb0d85690d53d…
Browse files Browse the repository at this point in the history
…6f56f6d42f5bea0f31d0786a

[main] OSS to ENT merge of (0cecb0d)
  • Loading branch information
hc-github-team-secure-boundary authored Jan 17, 2023
2 parents d5ae495 + a326d89 commit 8f1a223
Show file tree
Hide file tree
Showing 11 changed files with 340 additions and 33 deletions.
1 change: 1 addition & 0 deletions addons/core/translations/actions/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ fullscreen: Fullscreen
clear-all-filters: Clear all filters
learn-more: Learn more
refresh: Refresh
remove-resources: Remove resources and save
12 changes: 12 additions & 0 deletions addons/core/translations/resources/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ target:
add-host-sources: Add Host Sources
add-brokered-credential-sources: Add Brokered Credentials
add-injected-application-credential-sources: Add Injected Application Credentials
remove-address: Remove address and save
types:
tcp: Generic TCP
ssh: SSH
Expand All @@ -314,6 +315,13 @@ target:
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.
target-address:
label: Target Address
help: Must be a valid IP address or DNS name. We recommend leaving this blank and using host catalogs and host sets instead if you want to use this target on multiple hosts.
questions:
delete-host-sources:
title: Remove associated host sources?
message: You have {numHostSources, plural, one {# host source} other {# host sources}} associated with this target. Adding an address will remove these host sources when you save your changes.
host-source:
title: Host Source
title_plural: Host Sources
Expand All @@ -327,6 +335,10 @@ target:
add:
title: Add Host Sources
description: Select host sources to assign to this target.
questions:
delete-address:
title: Remove target address?
message: This target has an assigned address. Adding a host source will remove the assigned address from the target when you save your changes.
brokered-credential-source:
title: Brokered Credential
title_plural: Brokered Credentials
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{#if this.hasAvailableHostSets}}
<Rose::Form
class='full-width'
@onSubmit={{fn this.submit @submit}}
@onSubmit={{this.submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
as |form|
Expand Down
37 changes: 35 additions & 2 deletions ui/admin/app/components/form/target/add-host-sets/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import Component from '@glimmer/component';
import { computed, action } from '@ember/object';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';
import { loading } from 'ember-loading';
import { notifyError } from 'core/decorators/notify';

export default class FormTargetAddHostSetsComponent extends Component {
// =services

@service confirm;
@service intl;

// =properties

/**
Expand Down Expand Up @@ -49,7 +57,32 @@ export default class FormTargetAddHostSetsComponent extends Component {
}

@action
submit(fn) {
fn(this.selectedHostSetIDs);
@loading
@notifyError(({ message }) => message)
async submit() {
const target = this.args.model;

if (target.address && this.selectedHostSetIDs.length) {
try {
await this.confirm.confirm(
this.intl.t(
'resources.target.host-source.questions.delete-address.message'
),
{
title:
'resources.target.host-source.questions.delete-address.title',
confirm: 'resources.target.actions.remove-address',
}
);
} catch (e) {
// if the user denies, do nothing and return
return;
}

target.address = null;
await target.save();
}

await this.args.submit(this.selectedHostSetIDs);
}
}
78 changes: 52 additions & 26 deletions ui/admin/app/components/form/target/details/index.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Rose::Form
@onSubmit={{@submit}}
@onSubmit={{this.submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
@showEditToggle={{if @model.isNew false true}}
Expand Down Expand Up @@ -81,6 +81,57 @@
</InfoField>
{{/if}}

{{#if (feature-flag 'target-network-address')}}
<Hds::Form::TextInput::Field
@isRequired={{false}}
@isOptional={{true}}
@value={{@model.address}}
@isInvalid={{@model.errors.address}}
@type='text'
name='address'
disabled={{form.disabled}}
{{on 'input' (set-from-event @model 'address')}}
as |F|
>
<F.Label>{{t 'resources.target.form.target-address.label'}}</F.Label>
<F.HelperText>{{t
'resources.target.form.target-address.help'
}}</F.HelperText>
{{#if @model.errors.address}}
<F.Error as |E|>
{{#each @model.errors.address as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{/if}}

<Hds::Form::TextInput::Field
@isRequired={{@model.isTCP}}
@isOptional={{not @model.isTCP}}
@value={{@model.default_port}}
@isInvalid={{@model.errors.default_port}}
@type='text'
name='default_port'
disabled={{form.disabled}}
placeholder={{@defaultPort}}
{{on 'input' (set-from-event @model 'default_port')}}
as |F|
>
<F.Label data-test-default-port-label>{{t
'form.default_port.label'
}}</F.Label>
<F.HelperText>{{t 'form.default_port.help'}}</F.HelperText>
{{#if @model.errors.default_port}}
<F.Error as |E|>
{{#each @model.errors.default_port as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>

<Hds::Form::TextInput::Field
@isRequired={{false}}
@isOptional={{true}}
Expand Down Expand Up @@ -125,31 +176,6 @@
{{/if}}
</Hds::Form::TextInput::Field>

<Hds::Form::TextInput::Field
@isRequired={{@model.isTCP}}
@isOptional={{not @model.isTCP}}
@value={{@model.default_port}}
@isInvalid={{@model.errors.default_port}}
@type='text'
name='default_port'
disabled={{form.disabled}}
placeholder={{@defaultPort}}
{{on 'input' (set-from-event @model 'default_port')}}
as |F|
>
<F.Label data-test-default-port-label>{{t
'form.default_port.label'
}}</F.Label>
<F.HelperText>{{t 'form.default_port.help'}}</F.HelperText>
{{#if @model.errors.default_port}}
<F.Error as |E|>
{{#each @model.errors.default_port as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>

{{#if (feature-flag 'target-worker-filters-v2')}}
<Hds::Form::Fieldset
class='target-workers'
Expand Down
44 changes: 44 additions & 0 deletions ui/admin/app/components/form/target/details/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Component from '@glimmer/component';
import { TYPES_TARGET } from 'api/models/target';
import { loading } from 'ember-loading';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { notifyError } from 'core/decorators/notify';

// NOTE: this is all a temporary solution till we have a resource type helper.
const types = [...TYPES_TARGET].reverse();
Expand All @@ -9,6 +13,11 @@ const icons = {
};

export default class FormTargetComponent extends Component {
// =services

@service confirm;
@service intl;

// =properties
/**
* maps resource type with icon
Expand Down Expand Up @@ -37,4 +46,39 @@ export default class FormTargetComponent extends Component {
get showDeprecationMessage() {
return !this.args.model.isNew && this.args.model.worker_filter;
}

@action
@loading
@notifyError(({ message }) => message)
async submit() {
const target = this.args.model;
const numHostSources = target.host_sources?.length;
const address = target.address;
if (address && numHostSources) {
try {
await this.confirm.confirm(
this.intl.t(
'resources.target.questions.delete-host-sources.message',
{ numHostSources }
),
{
title: 'resources.target.questions.delete-host-sources.title',
confirm: 'actions.remove-resources',
}
);
} catch (e) {
// if the user denies, do nothing and return
return;
}

await target.removeHostSources(
target.host_sources.map((hs) => hs.host_source_id)
);
// After saving the host sources, the model gets reset to an empty address,
// so we need to update the address with the previous value before saving
target.address = address;
}

await this.args.submit();
}
}
2 changes: 1 addition & 1 deletion ui/admin/app/routes/scopes/scope/targets.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default class ScopesScopeTargetsRoute extends Route {
*/
@action
@loading
@notifyError(({ message }) => message)
@notifyError(({ message }) => message, { catch: true })
@notifySuccess(({ isNew }) =>
isNew ? 'notifications.create-success' : 'notifications.save-success'
)
Expand Down
6 changes: 5 additions & 1 deletion ui/admin/app/templates/application.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@
</dialog.body>
<dialog.footer>
<Rose::Button @style='primary' {{on 'click' accept}}>
{{t 'actions.ok'}}
{{if
confirmation.options.confirm
(t confirmation.options.confirm)
(t 'actions.ok')
}}
</Rose::Button>
<Rose::Button @style='secondary' {{on 'click' deny}}>
{{t 'actions.cancel'}}
Expand Down
31 changes: 29 additions & 2 deletions ui/admin/tests/acceptance/targets/create-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,13 @@ module('Acceptance | targets | create', function (hooks) {
);
});

test('defualt port is not marked required for SSH targets', async function (assert) {
test('default port is not marked required for SSH targets', async function (assert) {
assert.expect(1);
await visit(urls.newTarget);
assert.dom('[data-test-default-port-label]').includesText('Optional');
});

test('defualt port is marked required for TCP targets', async function (assert) {
test('default port is marked required for TCP targets', async function (assert) {
assert.expect(1);
await visit(urls.newTarget);
await click('[value="tcp"]');
Expand Down Expand Up @@ -285,4 +285,31 @@ module('Acceptance | targets | create', function (hooks) {
assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert.dom('.hds-form-error__message').hasText('Name is required.');
});

test('can save address', async function (assert) {
assert.expect(2);
const targetCount = getTargetCount();
await visit(urls.targets);

await click(`[href="${urls.newTarget}"]`);
await fillIn('[name="name"]', 'random string');
await fillIn('[name="address"]', '0.0.0.0');
await click('[type="submit"]');

assert.strictEqual(getTargetCount(), targetCount + 1);
assert.strictEqual(
this.server.schema.targets.all().models[getTargetCount() - 1].address,
'0.0.0.0'
);
});

test('address field does not exist when target network address feature is disabled', async function (assert) {
assert.expect(1);
featuresService.disable('target-network-address');
await visit(urls.targets);

await click(`[href="${urls.newTarget}"]`);

assert.dom('[name="address"]').doesNotExist();
});
});
Loading

0 comments on commit 8f1a223

Please sign in to comment.