mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 11:38:02 +00:00
UI: Build kv v2 patch page (#28114)
* build patch component * pass submit error to child component * add copyright header * aphabetize * rename kv-patch components * build json editor patch form * finish patch component and tests * use baseSetup in other kv tests * small styling changes * remove linting conditional, set json editor value on change * rename subkeys card * add reveal component to both patch forms * implement subkeys card * add copyright header, add transition assertions * assert flash spy * add assertion for empty values * separate tests into it does not submit module * update flash copy
This commit is contained in:
92
ui/lib/kv/addon/components/page/secret/patch.js
Normal file
92
ui/lib/kv/addon/components/page/secret/patch.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import Component from '@glimmer/component';
|
||||
import { service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { task } from 'ember-concurrency';
|
||||
import { waitFor } from '@ember/test-waiters';
|
||||
import errorMessage from 'vault/utils/error-message';
|
||||
|
||||
/**
|
||||
* @module KvSecretPatch
|
||||
* @description
|
||||
* This page template provides two methods for submitting patch data to update a KV v2 secret.
|
||||
* Either using a key/value form KvPatch::Editor::Form or the json editor via KvPatch::JsonForm
|
||||
*
|
||||
* <Page::Secret::Patch
|
||||
* @backend="my-kv-engine"
|
||||
* @breadcrumbs={{this.breadcrumbs}
|
||||
* @metadata={{this.model.metadata}}
|
||||
* @path="my-secret"
|
||||
* @subkeys={{this.subkeys}
|
||||
* @subkeysMeta={{this.subkeysMeta}
|
||||
* />
|
||||
*
|
||||
* @param {model} path - Secret path
|
||||
* @param {string} backend - Mount backend path
|
||||
* @param {model} metadata - Ember data model: 'kv/metadata'
|
||||
* @param {object} subkeys - subkeys (leaf keys with null values) of kv v2 secret
|
||||
* @param {object} subkeysMeta - metadata object returned from the /subkeys endpoint, contains: version, created_time, custom_metadata, deletion status and time
|
||||
* @param {array} breadcrumbs - breadcrumb objects to render in page header
|
||||
*/
|
||||
|
||||
export default class KvSecretPatch extends Component {
|
||||
@service controlGroup;
|
||||
@service flashMessages;
|
||||
@service router;
|
||||
@service store;
|
||||
|
||||
@tracked errorMessage;
|
||||
@tracked invalidFormAlert;
|
||||
@tracked patchMethod = 'UI';
|
||||
|
||||
@action
|
||||
selectPatchMethod(event) {
|
||||
this.patchMethod = event.target.value;
|
||||
}
|
||||
|
||||
@task
|
||||
@waitFor
|
||||
*save(patchData) {
|
||||
const isEmpty = this.isEmpty(patchData);
|
||||
if (isEmpty) {
|
||||
this.flashMessages.info(`No changes to submit. No updates made to "${this.args.path}".`);
|
||||
return this.onCancel();
|
||||
}
|
||||
|
||||
const { backend, path, metadata, subkeysMeta } = this.args;
|
||||
// if no metadata permission, use subkey metadata as backup
|
||||
const version = metadata.currentVersion || subkeysMeta.version;
|
||||
const adapter = this.store.adapterFor('kv/data');
|
||||
try {
|
||||
yield adapter.patchSecret(backend, path, patchData, version);
|
||||
this.flashMessages.success(`Successfully patched new version of ${path}.`);
|
||||
this.router.transitionTo('vault.cluster.secrets.backend.kv.secret');
|
||||
} catch (error) {
|
||||
// TODO test...this is copy pasta'd from the edit page
|
||||
let message = errorMessage(error);
|
||||
if (error.message === 'Control Group encountered') {
|
||||
this.controlGroup.saveTokenFromError(error);
|
||||
const err = this.controlGroup.logFromError(error);
|
||||
message = err.content;
|
||||
}
|
||||
this.errorMessage = message;
|
||||
this.invalidFormAlert = 'There was an error submitting this form.';
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
onCancel() {
|
||||
this.router.transitionTo('vault.cluster.secrets.backend.kv.secret');
|
||||
}
|
||||
|
||||
isEmpty(object) {
|
||||
const emptyKeys = Object.keys(object).every((k) => k === '');
|
||||
const emptyValues = Object.values(object).every((v) => v === '');
|
||||
return emptyKeys && emptyValues;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user