diff --git a/addons/api/addon/generated/models/credential-library.js b/addons/api/addon/generated/models/credential-library.js
index b72c2a008..548c4202b 100644
--- a/addons/api/addon/generated/models/credential-library.js
+++ b/addons/api/addon/generated/models/credential-library.js
@@ -75,6 +75,12 @@ 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('string', {
for: 'vault-ssh-certificate',
isNestedAttribute: true,
diff --git a/addons/api/addon/models/credential-library.js b/addons/api/addon/models/credential-library.js
index 197dec60b..001002e31 100644
--- a/addons/api/addon/models/credential-library.js
+++ b/addons/api/addon/models/credential-library.js
@@ -11,6 +11,7 @@ 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'],
};
export const TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC = 'vault-generic';
diff --git a/addons/api/tests/unit/serializers/credential-library-test.js b/addons/api/tests/unit/serializers/credential-library-test.js
index 52b7f7151..8cbce0bf5 100644
--- a/addons/api/tests/unit/serializers/credential-library-test.js
+++ b/addons/api/tests/unit/serializers/credential-library-test.js
@@ -23,6 +23,7 @@ module('Unit | Serializer | credential library', function (hooks) {
path: '/vault/path',
http_method: 'GET',
version: 1,
+ credential_type: 'ssh_private_key',
});
const snapshot = record._createSnapshot();
const serializedRecord = serializer.serialize(snapshot);
@@ -32,6 +33,7 @@ module('Unit | Serializer | credential library', function (hooks) {
name: 'Name',
description: 'Description',
version: 1,
+ credential_type: 'ssh_private_key',
attributes: {
path: '/vault/path',
http_method: 'GET',
@@ -54,6 +56,7 @@ module('Unit | Serializer | credential library', function (hooks) {
path: '/vault/path',
http_method: 'GET',
version: 1,
+ credential_type: 'ssh_private_key',
},
},
});
@@ -65,6 +68,7 @@ module('Unit | Serializer | credential library', function (hooks) {
credential_store_id: null,
name: 'Name',
description: 'Description',
+ credential_type: 'ssh_private_key',
attributes: {
path: '/vault/path',
http_method: 'GET',
@@ -80,6 +84,7 @@ module('Unit | Serializer | credential library', function (hooks) {
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
http_method: '',
path: null,
+ credential_type: null,
});
const vaultSSHCertificateRecord = store.createRecord('credential-library', {
type: TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
@@ -99,6 +104,7 @@ module('Unit | Serializer | credential library', function (hooks) {
description: null,
name: null,
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
+ credential_type: null,
});
assert.deepEqual(serializedVaultSSHCertificateRecord, {
attributes: {
@@ -138,6 +144,7 @@ module('Unit | Serializer | credential library', function (hooks) {
description: null,
name: null,
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
+ credential_type: null,
},
'http_request_body attribute is not expected',
);
@@ -156,6 +163,7 @@ module('Unit | Serializer | credential library', function (hooks) {
description: null,
name: null,
type: TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
+ credential_type: null,
},
'http_request_body attribute is expected',
);
diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml
index 0f23d9b57..462c11378 100644
--- a/addons/core/translations/resources/en-us.yaml
+++ b/addons/core/translations/resources/en-us.yaml
@@ -763,6 +763,8 @@ 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
actions:
create: New Credential Library
delete: Delete Credential Library
@@ -774,6 +776,9 @@ 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.
http_method:
label: HTTP Method
help: The HTTP method the library uses when requesting credentials from Vault.
diff --git a/ui/admin/app/components/form/credential-library/vault-generic/index.hbs b/ui/admin/app/components/form/credential-library/vault-generic/index.hbs
index 3bdd8aee4..ca40cbb81 100644
--- a/ui/admin/app/components/form/credential-library/vault-generic/index.hbs
+++ b/ui/admin/app/components/form/credential-library/vault-generic/index.hbs
@@ -108,6 +108,38 @@
{{/if}}
+
+
+ {{t 'resources.credential-library.form.credential_type.label'}}
+
+
+ {{t 'resources.credential-library.form.credential_type.help'}}
+
+
+
+
+ {{#each this.credentialTypes as |type|}}
+
+ {{/each}}
+
+ {{#if @model.errors.credential_type}}
+
+ {{#each @model.errors.credential_type as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
+
+
}
diff --git a/ui/admin/tests/acceptance/credential-library/create-test.js b/ui/admin/tests/acceptance/credential-library/create-test.js
index 94d3d68df..d979fdd35 100644
--- a/ui/admin/tests/acceptance/credential-library/create-test.js
+++ b/ui/admin/tests/acceptance/credential-library/create-test.js
@@ -88,12 +88,22 @@ 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 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');
});
test('can create a new credential library of type vault ssh cert', async function (assert) {
diff --git a/ui/admin/tests/acceptance/credential-library/update-test.js b/ui/admin/tests/acceptance/credential-library/update-test.js
index e83f10d0b..24156f3cb 100644
--- a/ui/admin/tests/acceptance/credential-library/update-test.js
+++ b/ui/admin/tests/acceptance/credential-library/update-test.js
@@ -191,6 +191,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('form [type="button"]', 'Activate edit mode');
+ assert.dom('[name=credential_type]').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,
@@ -226,6 +232,7 @@ 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"]');
const credentialLibrary = this.server.schema.credentialLibraries.findBy({