2023-03-01 09:39:41 -06:00
|
|
|
/**
|
2026-01-28 17:09:06 -08:00
|
|
|
* Copyright IBM Corp. 2021, 2026
|
2024-05-31 11:29:24 -07:00
|
|
|
* SPDX-License-Identifier: BUSL-1.1
|
2023-03-01 09:39:41 -06:00
|
|
|
*/
|
|
|
|
|
|
2020-08-21 11:53:53 -04:00
|
|
|
import GeneratedTargetModel from '../generated/models/target';
|
2022-01-18 13:44:27 -05:00
|
|
|
import { attr } from '@ember-data/model';
|
2025-03-12 08:29:54 -07:00
|
|
|
import { service } from '@ember/service';
|
2020-08-21 11:48:24 -04:00
|
|
|
|
2022-12-20 12:07:52 -05:00
|
|
|
export const TYPE_TARGET_TCP = 'tcp';
|
|
|
|
|
export const TYPE_TARGET_SSH = 'ssh';
|
2025-06-13 14:42:37 -07:00
|
|
|
export const TYPE_TARGET_RDP = 'rdp';
|
|
|
|
|
|
|
|
|
|
export const TYPES_TARGET = Object.freeze([
|
|
|
|
|
TYPE_TARGET_TCP,
|
|
|
|
|
TYPE_TARGET_SSH,
|
|
|
|
|
TYPE_TARGET_RDP,
|
|
|
|
|
]);
|
2022-12-08 11:17:44 -08:00
|
|
|
|
2020-08-24 18:03:45 -04:00
|
|
|
export default class TargetModel extends GeneratedTargetModel {
|
2022-11-07 15:17:23 -08:00
|
|
|
// =services
|
|
|
|
|
|
|
|
|
|
@service store;
|
|
|
|
|
|
2020-08-24 18:03:45 -04:00
|
|
|
// =attributes
|
|
|
|
|
|
2020-08-25 10:39:48 -04:00
|
|
|
/**
|
2022-08-31 09:55:59 -07:00
|
|
|
* @type Array
|
2020-08-25 10:39:48 -04:00
|
|
|
*/
|
2022-08-31 09:55:59 -07:00
|
|
|
@attr('host-source-id-array', {
|
2020-09-12 10:42:23 -04:00
|
|
|
readOnly: true,
|
2020-09-16 14:29:02 -04:00
|
|
|
emptyArrayIfMissing: true,
|
|
|
|
|
})
|
2021-09-22 19:15:09 -04:00
|
|
|
host_sources;
|
2020-08-24 18:03:45 -04:00
|
|
|
|
2021-07-20 16:09:59 -04:00
|
|
|
/**
|
2022-09-01 10:07:36 -07:00
|
|
|
* Brokered Credential source ids are read only and can be
|
2022-08-18 09:11:38 -07:00
|
|
|
* persisted via a dedicated call to `addBrokeredCredentialSources()`.
|
2021-07-20 16:09:59 -04:00
|
|
|
*/
|
2022-08-31 09:55:59 -07:00
|
|
|
@attr('string-array', {
|
2021-07-20 16:09:59 -04:00
|
|
|
readOnly: true,
|
|
|
|
|
emptyArrayIfMissing: true,
|
|
|
|
|
})
|
2022-08-15 09:48:12 -07:00
|
|
|
brokered_credential_source_ids;
|
2021-07-20 16:09:59 -04:00
|
|
|
|
2022-09-01 10:07:36 -07:00
|
|
|
/**
|
|
|
|
|
* Injected Application Credential source ids are read only and can be
|
|
|
|
|
* persisted via a dedicated call to `addInjectedApplicationCredentialSources()`.
|
|
|
|
|
*/
|
|
|
|
|
@attr('string-array', {
|
|
|
|
|
readOnly: true,
|
|
|
|
|
emptyArrayIfMissing: true,
|
|
|
|
|
})
|
|
|
|
|
injected_application_credential_source_ids;
|
|
|
|
|
|
2020-08-25 10:39:48 -04:00
|
|
|
/**
|
|
|
|
|
* An array of resolved host set and host catalog instances. Model instances
|
|
|
|
|
* must already be loaded into the store (this method will not load unloaded
|
|
|
|
|
* instances). Unresolvable instances are excluded from the array.
|
|
|
|
|
* @type {[{model: HostSetModel, hostCatalog: HostCatalogModel}]}
|
|
|
|
|
*/
|
|
|
|
|
get hostSets() {
|
2021-09-22 19:15:09 -04:00
|
|
|
return this.host_sources
|
2021-09-21 09:37:47 -04:00
|
|
|
.map(({ host_source_id, host_catalog_id }) => ({
|
|
|
|
|
model: this.store.peekRecord('host-set', host_source_id),
|
2020-09-16 14:29:02 -04:00
|
|
|
hostCatalog: this.store.peekRecord('host-catalog', host_catalog_id),
|
2020-08-25 10:39:48 -04:00
|
|
|
}))
|
2020-09-16 14:29:02 -04:00
|
|
|
.filter((hostSetRef) => hostSetRef.model !== null);
|
2020-08-25 10:39:48 -04:00
|
|
|
}
|
|
|
|
|
|
2021-07-21 15:45:45 -04:00
|
|
|
/**
|
2022-08-08 09:21:07 -07:00
|
|
|
* An array of resolved credential library and credential instances. Model instances
|
2021-07-21 15:45:45 -04:00
|
|
|
* must already be loaded into the store (this method will not load unloaded
|
|
|
|
|
* instances). Unresolvable instances are excluded from the array.
|
2022-08-08 09:21:07 -07:00
|
|
|
* @type {[CredentialLibraryModel, CredentialModel]}
|
2021-07-21 15:45:45 -04:00
|
|
|
*/
|
2022-08-18 09:11:38 -07:00
|
|
|
get brokeredCredentialSources() {
|
2022-08-15 09:48:12 -07:00
|
|
|
return this.brokered_credential_source_ids
|
2022-08-08 09:21:07 -07:00
|
|
|
.map((source) => {
|
|
|
|
|
if (source.value.startsWith('cred')) {
|
|
|
|
|
return this.store.peekRecord('credential', source.value);
|
|
|
|
|
} else {
|
|
|
|
|
return this.store.peekRecord('credential-library', source.value);
|
|
|
|
|
}
|
|
|
|
|
})
|
2021-07-21 15:45:45 -04:00
|
|
|
.filter(Boolean);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-01 10:07:36 -07:00
|
|
|
/**
|
|
|
|
|
* An array of resolved credential library and credential instances. Model instances
|
|
|
|
|
* must already be loaded into the store (this method will not load unloaded
|
|
|
|
|
* instances). Unresolvable instances are excluded from the array.
|
|
|
|
|
* @type {[CredentialLibraryModel, CredentialModel]}
|
|
|
|
|
*/
|
|
|
|
|
get injectedApplicationCredentialSources() {
|
|
|
|
|
return this.injected_application_credential_source_ids
|
|
|
|
|
.map((source) => {
|
|
|
|
|
if (source.value.startsWith('cred')) {
|
|
|
|
|
return this.store.peekRecord('credential', source.value);
|
|
|
|
|
} else {
|
|
|
|
|
return this.store.peekRecord('credential-library', source.value);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-05 16:57:06 -05:00
|
|
|
/**
|
|
|
|
|
* Sessions associated with this target (but only already loaded sessions).
|
|
|
|
|
* @type {SessionModel[]}
|
|
|
|
|
*/
|
|
|
|
|
get sessions() {
|
2021-03-04 15:47:38 -05:00
|
|
|
return this.store
|
|
|
|
|
.peekAll('session')
|
|
|
|
|
.filter((s) => s && s.target_id === this.id);
|
2021-02-05 16:57:06 -05:00
|
|
|
}
|
|
|
|
|
|
2023-12-22 09:56:07 -08:00
|
|
|
/**
|
|
|
|
|
* Available sessions associated with this target (but only already loaded sessions).
|
|
|
|
|
* @type {SessionModel[]}
|
|
|
|
|
*/
|
|
|
|
|
get availableSessions() {
|
|
|
|
|
return this.sessions.filter((session) => session.isAvailable);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-10 13:19:24 -05:00
|
|
|
/**
|
|
|
|
|
* The project associated with this target (if already loaded).
|
|
|
|
|
* @type {ScopeModel}
|
|
|
|
|
*/
|
|
|
|
|
get project() {
|
|
|
|
|
return this.store.peekRecord('scope', this.scopeID);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-05 16:57:06 -05:00
|
|
|
/**
|
|
|
|
|
* True if any sessions associated with this target are active or pending.
|
|
|
|
|
* @type {boolean}
|
|
|
|
|
*/
|
|
|
|
|
get isActive() {
|
2021-03-04 15:47:38 -05:00
|
|
|
const pendingOrActiveSessions = this.sessions.filter(
|
2023-11-22 14:07:41 -05:00
|
|
|
(s) => s.isActive || s.isPending,
|
2021-03-04 15:47:38 -05:00
|
|
|
);
|
2021-02-05 16:57:06 -05:00
|
|
|
return Boolean(pendingOrActiveSessions.length);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-19 16:18:32 -04:00
|
|
|
get associatedAliases() {
|
|
|
|
|
return this.store
|
|
|
|
|
.peekAll('alias')
|
|
|
|
|
.filter((alias) => alias?.destination_id === this.id);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-24 18:03:45 -04:00
|
|
|
// =methods
|
|
|
|
|
|
|
|
|
|
/**
|
2021-09-22 18:52:38 -04:00
|
|
|
* Adds host sets via the `add-host-sources` method.
|
2020-08-24 18:03:45 -04:00
|
|
|
* See serializer and adapter for more information.
|
2020-08-26 14:03:43 -04:00
|
|
|
* @param {[string]} hostSetIDs
|
2020-08-24 18:03:45 -04:00
|
|
|
* @param {object} options
|
|
|
|
|
* @param {object} options.adapterOptions
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
2021-09-21 14:53:56 -04:00
|
|
|
addHostSources(hostSetIDs, options = { adapterOptions: {} }) {
|
2020-08-25 10:39:48 -04:00
|
|
|
const defaultAdapterOptions = {
|
2021-09-22 18:52:38 -04:00
|
|
|
method: 'add-host-sources',
|
2020-09-16 14:29:02 -04:00
|
|
|
hostSetIDs,
|
2020-08-26 13:52:54 -04:00
|
|
|
};
|
|
|
|
|
// There is no "deep merge" in ES.
|
|
|
|
|
return this.save({
|
|
|
|
|
...options,
|
|
|
|
|
adapterOptions: {
|
|
|
|
|
...defaultAdapterOptions,
|
2020-09-16 14:29:02 -04:00
|
|
|
...options.adapterOptions,
|
|
|
|
|
},
|
2020-08-26 13:52:54 -04:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2021-09-22 18:52:38 -04:00
|
|
|
* Delete host sets via the `remove-host-sources` method.
|
2020-08-26 13:52:54 -04:00
|
|
|
* See serializer and adapter for more information.
|
2020-08-26 14:03:43 -04:00
|
|
|
* @param {[string]} hostSetIDs
|
2020-08-26 13:52:54 -04:00
|
|
|
* @param {object} options
|
|
|
|
|
* @param {object} options.adapterOptions
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
2021-09-21 14:53:56 -04:00
|
|
|
removeHostSources(hostSetIDs, options = { adapterOptions: {} }) {
|
2020-08-26 13:52:54 -04:00
|
|
|
const defaultAdapterOptions = {
|
2021-09-22 18:52:38 -04:00
|
|
|
method: 'remove-host-sources',
|
2020-09-16 14:29:02 -04:00
|
|
|
hostSetIDs,
|
2020-08-24 18:03:45 -04:00
|
|
|
};
|
|
|
|
|
// There is no "deep merge" in ES.
|
|
|
|
|
return this.save({
|
|
|
|
|
...options,
|
|
|
|
|
adapterOptions: {
|
2020-08-25 10:39:48 -04:00
|
|
|
...defaultAdapterOptions,
|
2020-09-16 14:29:02 -04:00
|
|
|
...options.adapterOptions,
|
|
|
|
|
},
|
2020-08-24 18:03:45 -04:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-27 12:59:26 -04:00
|
|
|
/**
|
2021-09-22 18:52:38 -04:00
|
|
|
* Delete a single host set via the `remove-host-sources` method.
|
2020-08-27 15:21:40 -04:00
|
|
|
* @param {number} hostSetID
|
2020-08-27 12:59:26 -04:00
|
|
|
* @param {object} options
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
2021-09-21 14:53:56 -04:00
|
|
|
removeHostSource(hostSetID, options) {
|
|
|
|
|
return this.removeHostSources([hostSetID], options);
|
2020-08-27 12:59:26 -04:00
|
|
|
}
|
2021-07-21 15:45:45 -04:00
|
|
|
|
|
|
|
|
/**
|
2022-08-08 09:21:07 -07:00
|
|
|
* Adds credential sources via the `add-credential-sources` method.
|
2021-07-21 15:45:45 -04:00
|
|
|
* See serializer and adapter for more information.
|
2022-09-01 10:07:36 -07:00
|
|
|
* @param {[string]} brokeredCredentialSourceIDs
|
2021-07-21 15:45:45 -04:00
|
|
|
* @param {object} options
|
|
|
|
|
* @param {object} options.adapterOptions
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
2022-08-18 09:11:38 -07:00
|
|
|
addBrokeredCredentialSources(
|
2022-09-01 10:07:36 -07:00
|
|
|
brokeredCredentialSourceIDs,
|
2023-11-22 14:07:41 -05:00
|
|
|
options = { adapterOptions: {} },
|
2022-09-01 10:07:36 -07:00
|
|
|
) {
|
|
|
|
|
const defaultAdapterOptions = {
|
|
|
|
|
method: 'add-credential-sources',
|
|
|
|
|
brokeredCredentialSourceIDs,
|
|
|
|
|
};
|
|
|
|
|
// There is no "deep merge" in ES.
|
|
|
|
|
return this.save({
|
|
|
|
|
...options,
|
|
|
|
|
adapterOptions: {
|
|
|
|
|
...defaultAdapterOptions,
|
|
|
|
|
...options.adapterOptions,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds credential sources via the `add-credential-sources` method.
|
|
|
|
|
* See serializer and adapter for more information.
|
|
|
|
|
* @param {[string]} injectedApplicationCredentialSourceIDs
|
|
|
|
|
* @param {object} options
|
|
|
|
|
* @param {object} options.adapterOptions
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
|
|
|
|
addInjectedApplicationCredentialSources(
|
|
|
|
|
injectedApplicationCredentialSourceIDs,
|
2023-11-22 14:07:41 -05:00
|
|
|
options = { adapterOptions: {} },
|
2022-08-18 09:11:38 -07:00
|
|
|
) {
|
2021-07-21 15:45:45 -04:00
|
|
|
const defaultAdapterOptions = {
|
2021-09-22 18:34:35 -04:00
|
|
|
method: 'add-credential-sources',
|
2022-09-01 10:07:36 -07:00
|
|
|
injectedApplicationCredentialSourceIDs,
|
2021-07-21 15:45:45 -04:00
|
|
|
};
|
|
|
|
|
// There is no "deep merge" in ES.
|
|
|
|
|
return this.save({
|
|
|
|
|
...options,
|
|
|
|
|
adapterOptions: {
|
|
|
|
|
...defaultAdapterOptions,
|
|
|
|
|
...options.adapterOptions,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-08-08 09:21:07 -07:00
|
|
|
* Delete credential libraries and credentials via the `remove-credential-sources` method.
|
2021-07-21 15:45:45 -04:00
|
|
|
* See serializer and adapter for more information.
|
2022-09-01 10:07:36 -07:00
|
|
|
* @param {[string]} brokeredCredentialSourceIDs
|
2021-07-21 15:45:45 -04:00
|
|
|
* @param {object} options
|
|
|
|
|
* @param {object} options.adapterOptions
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
2022-08-18 09:11:38 -07:00
|
|
|
removeBrokeredCredentialSources(
|
2022-09-01 10:07:36 -07:00
|
|
|
brokeredCredentialSourceIDs,
|
2023-11-22 14:07:41 -05:00
|
|
|
options = { adapterOptions: {} },
|
2021-07-21 15:45:45 -04:00
|
|
|
) {
|
|
|
|
|
const defaultAdapterOptions = {
|
2021-09-22 18:34:35 -04:00
|
|
|
method: 'remove-credential-sources',
|
2022-09-01 10:07:36 -07:00
|
|
|
brokeredCredentialSourceIDs,
|
2021-07-21 15:45:45 -04:00
|
|
|
};
|
|
|
|
|
// There is no "deep merge" in ES.
|
|
|
|
|
return this.save({
|
|
|
|
|
...options,
|
|
|
|
|
adapterOptions: {
|
|
|
|
|
...defaultAdapterOptions,
|
|
|
|
|
...options.adapterOptions,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-08-08 09:21:07 -07:00
|
|
|
* Delete a single credential library/credential set via the `remove-credential-sources` method.
|
2022-09-01 10:07:36 -07:00
|
|
|
* @param {number} brokeredCredentialSourceID
|
2021-07-21 15:45:45 -04:00
|
|
|
* @param {object} options
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
2022-09-01 10:07:36 -07:00
|
|
|
removeBrokeredCredentialSource(brokeredCredentialSourceID, options) {
|
|
|
|
|
return this.removeBrokeredCredentialSources(
|
|
|
|
|
[brokeredCredentialSourceID],
|
2023-11-22 14:07:41 -05:00
|
|
|
options,
|
2022-09-01 10:07:36 -07:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Delete credential libraries and credentials via the `remove-credential-sources` method.
|
|
|
|
|
* See serializer and adapter for more information.
|
|
|
|
|
* @param {[string]} injectedApplicationCredentialSourceIDs
|
|
|
|
|
* @param {object} options
|
|
|
|
|
* @param {object} options.adapterOptions
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
|
|
|
|
removeInjectedApplicationCredentialSources(
|
|
|
|
|
injectedApplicationCredentialSourceIDs,
|
2023-11-22 14:07:41 -05:00
|
|
|
options = { adapterOptions: {} },
|
2022-09-01 10:07:36 -07:00
|
|
|
) {
|
|
|
|
|
const defaultAdapterOptions = {
|
|
|
|
|
method: 'remove-credential-sources',
|
|
|
|
|
injectedApplicationCredentialSourceIDs,
|
|
|
|
|
};
|
|
|
|
|
// There is no "deep merge" in ES.
|
|
|
|
|
return this.save({
|
|
|
|
|
...options,
|
|
|
|
|
adapterOptions: {
|
|
|
|
|
...defaultAdapterOptions,
|
|
|
|
|
...options.adapterOptions,
|
|
|
|
|
},
|
|
|
|
|
});
|
2021-07-21 15:45:45 -04:00
|
|
|
}
|
2022-03-14 09:53:57 -07:00
|
|
|
|
2022-09-01 10:07:36 -07:00
|
|
|
/**
|
|
|
|
|
* Delete a single credential library/credential set via the `remove-credential-sources` method.
|
|
|
|
|
* @param {number} injectedApplicationCredentialSourceID
|
|
|
|
|
* @param {object} options
|
|
|
|
|
* @return {Promise}
|
|
|
|
|
*/
|
|
|
|
|
removeInjectedApplicationCredentialSource(
|
|
|
|
|
injectedApplicationCredentialSourceID,
|
2023-11-22 14:07:41 -05:00
|
|
|
options,
|
2022-09-01 10:07:36 -07:00
|
|
|
) {
|
|
|
|
|
return this.removeInjectedApplicationCredentialSources(
|
|
|
|
|
[injectedApplicationCredentialSourceID],
|
2023-11-22 14:07:41 -05:00
|
|
|
options,
|
2022-09-01 10:07:36 -07:00
|
|
|
);
|
|
|
|
|
}
|
2023-03-22 10:52:33 -04:00
|
|
|
|
2022-03-14 09:53:57 -07:00
|
|
|
/**
|
|
|
|
|
* True if the target type is tcp.
|
|
|
|
|
* @type {boolean}
|
|
|
|
|
*/
|
|
|
|
|
get isTCP() {
|
2022-12-20 12:07:52 -05:00
|
|
|
return this.type === TYPE_TARGET_TCP;
|
2022-03-14 09:53:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* True if the target type is ssh.
|
|
|
|
|
* @type {boolean}
|
|
|
|
|
*/
|
|
|
|
|
get isSSH() {
|
2022-12-20 12:07:52 -05:00
|
|
|
return this.type === TYPE_TARGET_SSH;
|
2022-03-14 09:53:57 -07:00
|
|
|
}
|
2025-06-13 14:42:37 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* True if the target type is rdp.
|
|
|
|
|
* @type {boolean}
|
|
|
|
|
*/
|
|
|
|
|
get isRDP() {
|
|
|
|
|
return this.type === TYPE_TARGET_RDP;
|
|
|
|
|
}
|
2020-08-24 18:03:45 -04:00
|
|
|
}
|