Merge branch 'main' into test-credential-library-create-errors
This commit is contained in:
7 files changed
+328
-17
No files matched your search
@@ -19,6 +19,16 @@ export default class FragmentCredentialStoreAttributesSerializer extends JSONSer
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Token cannot be unset. If it's falsy, it must be removed.
|
||||
if (key === 'token' && !json[key]) delete json[key];
|
||||
// Client certificate key cannot be unset when certificate is set.
|
||||
// If it's falsy, it must be removed.
|
||||
if (
|
||||
key === 'client_certificate_key' &&
|
||||
!json[key] &&
|
||||
json['client_certificate']
|
||||
)
|
||||
delete json[key];
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -6,26 +6,112 @@ module(
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor(
|
||||
'fragment-credential-store-attributes'
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-store-attributes',
|
||||
{
|
||||
address: '',
|
||||
ca_cert: '',
|
||||
client_certificate: '',
|
||||
client_certificate_key: '',
|
||||
namespace: '',
|
||||
tls_server_name: '',
|
||||
tls_skip_verify: false,
|
||||
}
|
||||
);
|
||||
|
||||
assert.ok(serializer);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
address: null,
|
||||
ca_cert: null,
|
||||
client_certificate: null,
|
||||
client_certificate_key: null,
|
||||
namespace: null,
|
||||
tls_server_name: null,
|
||||
tls_skip_verify: false,
|
||||
});
|
||||
});
|
||||
|
||||
test('it serializes records', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord(
|
||||
test('it does not serialize token if present but falsy', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-store-attributes',
|
||||
{}
|
||||
{
|
||||
token: null,
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
'token attribute is not expected'
|
||||
);
|
||||
});
|
||||
|
||||
test('it does not serialize client certificate key if present but falsy when client certificate is present', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-store-attributes',
|
||||
{
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: '',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
client_certificate: 'client-cert-123',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
'client certificate key attribute is not expected'
|
||||
);
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
record.client_certificate_key = 'client-cert-key-456';
|
||||
serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
'client certificate key attribute is expected'
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -290,6 +290,35 @@ credential-store:
|
||||
delete: Delete Credential Store
|
||||
types:
|
||||
vault: Vault
|
||||
form:
|
||||
address:
|
||||
label: Address
|
||||
help: The address of the Vault server. This should be a complete URL such as https://127.0.0.1:8200.
|
||||
namespace:
|
||||
label: Namespace
|
||||
help: A Vault namespace. Requires Vault Enterprise.
|
||||
ca_cert:
|
||||
label: CA Certificate
|
||||
help: A PEM-encoded CA certificate to verify the Vault server's TLS certificate.
|
||||
tls_server_name:
|
||||
label: TLS Server Name
|
||||
help: Name to use as the SNI host when connecting to Vault via TLS.
|
||||
tls_skip_verify:
|
||||
label: TLS Skip Verify
|
||||
help: Disable verification of TLS certificates. Using this option is highly discouraged as it decreases the security of data transmissions to and from the Vault server.
|
||||
token:
|
||||
label: Token
|
||||
help: A token used for accessing Vault.
|
||||
token_hmac:
|
||||
label: Token HMAC
|
||||
client_certificate:
|
||||
label: Client Certificate
|
||||
help: A PEM-encoded client certificate to use for TLS authentication to the Vault server.
|
||||
client_certificate_key:
|
||||
label: Client Certificate Key
|
||||
help: A PEM-encoded private key matching the client certificate from Client Certificate.
|
||||
client_certificate_key_hmac:
|
||||
label: Client Certificate Key HMAC
|
||||
credential-library:
|
||||
title: Credential Library
|
||||
title_plural: Credential Libraries
|
||||
|
||||
@@ -52,6 +52,188 @@
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.input
|
||||
@name='address'
|
||||
@type='text'
|
||||
@value={{@model.attributes.address}}
|
||||
@label={{t 'resources.credential-store.form.address.label'}}
|
||||
@error={{@model.errors.attributes_address}}
|
||||
@helperText={{t 'resources.credential-store.form.address.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_address}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_address as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.input
|
||||
@name='token'
|
||||
@type='text'
|
||||
@value={{@model.attributes.token}}
|
||||
@label={{t 'resources.credential-store.form.token.label'}}
|
||||
@error={{@model.errors.attributes_token}}
|
||||
@helperText={{t 'resources.credential-store.form.token.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_token}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_token as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
{{#unless @model.isNew}}
|
||||
<form.input
|
||||
@value={{@model.attributes.token_hmac}}
|
||||
@label={{t 'resources.credential-store.form.token_hmac.label'}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
{{/unless}}
|
||||
|
||||
<form.input
|
||||
@name='namespace'
|
||||
@type='text'
|
||||
@value={{@model.attributes.namespace}}
|
||||
@label={{t 'resources.credential-store.form.namespace.label'}}
|
||||
@error={{@model.errors.attributes_namespace}}
|
||||
@helperText={{t 'resources.credential-store.form.namespace.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_namespace}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_namespace as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.input
|
||||
@name='tls_server_name'
|
||||
@type='text'
|
||||
@value={{@model.attributes.tls_server_name}}
|
||||
@label={{t 'resources.credential-store.form.tls_server_name.label'}}
|
||||
@error={{@model.errors.attributes_tls_server_name}}
|
||||
@helperText={{t 'resources.credential-store.form.tls_server_name.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_tls_server_name}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_tls_server_name as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.input>
|
||||
|
||||
<form.checkbox
|
||||
@label={{t 'resources.credential-store.form.tls_skip_verify.label'}}
|
||||
@helperText={{t 'resources.credential-store.form.tls_skip_verify.help'}}
|
||||
@checked={{@model.attributes.tls_skip_verify}}
|
||||
onChange={{fn
|
||||
(mut @model.attributes.tls_skip_verify)
|
||||
(if @model.attributes.tls_skip_verify false true)
|
||||
}}
|
||||
@error={{@model.errors.attributes_tls_skip_verify}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_tls_skip_verify}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_tls_skip_verify as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.checkbox>
|
||||
|
||||
<form.textarea
|
||||
@name='client_certificate'
|
||||
@type='text'
|
||||
@value={{@model.attributes.client_certificate}}
|
||||
@label={{t 'resources.credential-store.form.client_certificate.label'}}
|
||||
@error={{@model.errors.attributes_client_certificate}}
|
||||
@helperText={{t 'resources.credential-store.form.client_certificate.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_client_certificate}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_client_certificate as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.textarea
|
||||
@name='client_certificate_key'
|
||||
@type='text'
|
||||
@value={{@model.attributes.client_certificate_key}}
|
||||
@label={{t 'resources.credential-store.form.client_certificate_key.label'}}
|
||||
@error={{@model.errors.attributes_client_certificate_key}}
|
||||
@helperText={{t
|
||||
'resources.credential-store.form.client_certificate_key.help'
|
||||
}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_client_certificate_key}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_client_certificate_key as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
{{#unless @model.isNew}}
|
||||
<form.input
|
||||
@value={{@model.attributes.client_certificate_key_hmac}}
|
||||
@label={{t
|
||||
'resources.credential-store.form.client_certificate_key_hmac.label'
|
||||
}}
|
||||
readonly={{true}}
|
||||
@disabled={{true}}
|
||||
/>
|
||||
{{/unless}}
|
||||
|
||||
<form.textarea
|
||||
@name='ca_cert'
|
||||
@type='text'
|
||||
@value={{@model.attributes.ca_cert}}
|
||||
@label={{t 'resources.credential-store.form.ca_cert.label'}}
|
||||
@error={{@model.errors.attributes_ca_cert}}
|
||||
@helperText={{t 'resources.credential-store.form.ca_cert.help'}}
|
||||
disabled={{@model.isSaving}}
|
||||
readonly={{false}}
|
||||
as |field|
|
||||
>
|
||||
{{#if @model.errors.attributes_ca_cert}}
|
||||
<field.errors as |errors|>
|
||||
{{#each @model.errors.attributes_ca_cert as |error|}}
|
||||
<errors.message>{{error.message}}</errors.message>
|
||||
{{/each}}
|
||||
</field.errors>
|
||||
{{/if}}
|
||||
</form.textarea>
|
||||
|
||||
<form.actions
|
||||
@disabled={{if @model.cannotSave @model.cannotSave}}
|
||||
@enableEditText={{t 'actions.edit-form'}}
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
<h2>{{t 'resources.credential-library.title'}}</h2>
|
||||
<h2>
|
||||
{{t 'resources.credential-library.title'}}
|
||||
<DocLink @doc='credential-source' @iconSize='large' />
|
||||
</h2>
|
||||
<p>{{t 'resources.credential-library.description'}}</p>
|
||||
<Copyable
|
||||
@text={{@model.id}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<page.header>
|
||||
<h2>
|
||||
{{t 'resources.credential-store.title_plural'}}
|
||||
<DocLink @doc='credential-stores' @iconSize='large' />
|
||||
<DocLink @doc='credential-store' @iconSize='large' />
|
||||
</h2>
|
||||
{{#if @model}}
|
||||
<p>{{t 'resources.credential-store.description'}}</p>
|
||||
|
||||
@@ -55,7 +55,8 @@ module.exports = function (environment) {
|
||||
'host-set': '/host-sets',
|
||||
'host-set.new': '/host-sets/new',
|
||||
'host-set.add-hosts': '/host-sets/add-hosts',
|
||||
'credential-stores': '/credential-stores',
|
||||
'credential-store': '/credential-stores',
|
||||
'credential-source': '/credential-sources',
|
||||
host: '/hosts',
|
||||
'host.new': '/hosts/new',
|
||||
role: '/roles',
|
||||
|
||||
Reference in new issue
Block a user