mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
# Backport This will backport the following commits from `main` to `8.11`: - [[Fleet] Support integration secrets with `required: false` (#172078)](https://github.com/elastic/kibana/pull/172078) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Kyle Pollich","email":"kyle.pollich@elastic.co"},"sourceCommit":{"committedDate":"2023-11-28T16:52:01Z","message":"[Fleet] Support integration secrets with `required: false` (#172078)\n\n## Summary\r\n\r\nSupport secrets with `required: false` in package manifests.\r\n\r\nCloses #172061\r\n\r\n## To test\r\n\r\n1. Set up an integration in a local package registry with a variable\r\nthat has `secret: true` and `required: false`, e.g.\r\n\r\n```yml\r\n- name: secret_token\r\n type: password\r\n title: (Test) Secret Token\r\n description: |\r\n Test non-required secret\r\n show_user: true\r\n secret: true\r\n required: false\r\n```\r\n\r\n2. Create a package policy for your test package and note the optional\r\nsecret is rendered properly\r\n3. Submit the policy editor form without filling out a value for the\r\noptional secret\r\n4. Observe the request is successful\r\n5. Edit the package policy and set a value for the optional secret\r\n6. Observe that the secret creation logic works as expected\r\n\r\n## Screen recording\r\n\r\n\r\n36e271c5
-29d0-49f8-91e8-abc6a7871b20","sha":"e64f475a013e1160f0938e14f8da7dcbf97a44bb","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Fleet","backport:prev-minor","v8.12.0"],"number":172078,"url":"https://github.com/elastic/kibana/pull/172078","mergeCommit":{"message":"[Fleet] Support integration secrets with `required: false` (#172078)\n\n## Summary\r\n\r\nSupport secrets with `required: false` in package manifests.\r\n\r\nCloses #172061\r\n\r\n## To test\r\n\r\n1. Set up an integration in a local package registry with a variable\r\nthat has `secret: true` and `required: false`, e.g.\r\n\r\n```yml\r\n- name: secret_token\r\n type: password\r\n title: (Test) Secret Token\r\n description: |\r\n Test non-required secret\r\n show_user: true\r\n secret: true\r\n required: false\r\n```\r\n\r\n2. Create a package policy for your test package and note the optional\r\nsecret is rendered properly\r\n3. Submit the policy editor form without filling out a value for the\r\noptional secret\r\n4. Observe the request is successful\r\n5. Edit the package policy and set a value for the optional secret\r\n6. Observe that the secret creation logic works as expected\r\n\r\n## Screen recording\r\n\r\n\r\n36e271c5
-29d0-49f8-91e8-abc6a7871b20","sha":"e64f475a013e1160f0938e14f8da7dcbf97a44bb"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.12.0","labelRegex":"^v8.12.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/172078","number":172078,"mergeCommit":{"message":"[Fleet] Support integration secrets with `required: false` (#172078)\n\n## Summary\r\n\r\nSupport secrets with `required: false` in package manifests.\r\n\r\nCloses #172061\r\n\r\n## To test\r\n\r\n1. Set up an integration in a local package registry with a variable\r\nthat has `secret: true` and `required: false`, e.g.\r\n\r\n```yml\r\n- name: secret_token\r\n type: password\r\n title: (Test) Secret Token\r\n description: |\r\n Test non-required secret\r\n show_user: true\r\n secret: true\r\n required: false\r\n```\r\n\r\n2. Create a package policy for your test package and note the optional\r\nsecret is rendered properly\r\n3. Submit the policy editor form without filling out a value for the\r\noptional secret\r\n4. Observe the request is successful\r\n5. Edit the package policy and set a value for the optional secret\r\n6. Observe that the secret creation logic works as expected\r\n\r\n## Screen recording\r\n\r\n\r\n36e271c5
-29d0-49f8-91e8-abc6a7871b20","sha":"e64f475a013e1160f0938e14f8da7dcbf97a44bb"}}]}] BACKPORT--> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
c504960d67
commit
c4b7c82eae
3 changed files with 834 additions and 707 deletions
|
@ -338,8 +338,8 @@ const SecretFieldWrapper = ({ children }: { children: React.ReactNode }) => {
|
|||
const SecretFieldLabel = ({ fieldLabel }: { fieldLabel: string }) => {
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup alignItems="center" gutterSize="xs">
|
||||
<EuiFlexItem grow={true} aria-label={fieldLabel}>
|
||||
<EuiFlexGroup alignItems="flexEnd" gutterSize="xs">
|
||||
<EuiFlexItem grow={false} aria-label={fieldLabel}>
|
||||
{fieldLabel}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
|
@ -376,12 +376,37 @@ function SecretInputField({
|
|||
setIsDirty,
|
||||
isDirty,
|
||||
}: InputComponentProps) {
|
||||
const [editMode, setEditMode] = useState(isEditPage && !value);
|
||||
const [isReplacing, setIsReplacing] = useState(isEditPage && !value);
|
||||
const valueOnFirstRender = useRef(value);
|
||||
|
||||
const hasExistingValue = !!valueOnFirstRender.current;
|
||||
const lowercaseTitle = varDef.title?.toLowerCase();
|
||||
const showInactiveReplaceUi = isEditPage && !isReplacing && hasExistingValue;
|
||||
const valueIsSecretRef = value && value?.isSecretRef;
|
||||
|
||||
if (isEditPage && !editMode) {
|
||||
const inputComponent = getInputComponent({
|
||||
varDef,
|
||||
value: isReplacing && valueIsSecretRef ? '' : value,
|
||||
onChange,
|
||||
frozen,
|
||||
packageName,
|
||||
packageType,
|
||||
datastreams,
|
||||
isEditPage,
|
||||
isInvalid,
|
||||
fieldLabel,
|
||||
fieldTestSelector,
|
||||
isDirty,
|
||||
setIsDirty,
|
||||
});
|
||||
|
||||
// If there's no value for this secret, display the input as its "brand new" creation state
|
||||
// instead of the "replace" state
|
||||
if (!hasExistingValue) {
|
||||
return inputComponent;
|
||||
}
|
||||
|
||||
if (showInactiveReplaceUi) {
|
||||
return (
|
||||
<>
|
||||
<EuiText size="s" color="subdued">
|
||||
|
@ -395,7 +420,7 @@ function SecretInputField({
|
|||
</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiButtonEmpty
|
||||
onClick={() => setEditMode(true)}
|
||||
onClick={() => setIsReplacing(true)}
|
||||
color="primary"
|
||||
iconType="refresh"
|
||||
iconSide="left"
|
||||
|
@ -413,28 +438,11 @@ function SecretInputField({
|
|||
);
|
||||
}
|
||||
|
||||
const valueIsSecretRef = value && value?.isSecretRef;
|
||||
const field = getInputComponent({
|
||||
varDef,
|
||||
value: editMode && valueIsSecretRef ? '' : value,
|
||||
onChange,
|
||||
frozen,
|
||||
packageName,
|
||||
packageType,
|
||||
datastreams,
|
||||
isEditPage,
|
||||
isInvalid,
|
||||
fieldLabel,
|
||||
fieldTestSelector,
|
||||
isDirty,
|
||||
setIsDirty,
|
||||
});
|
||||
|
||||
if (editMode) {
|
||||
if (isReplacing) {
|
||||
const cancelButton = (
|
||||
<EuiButtonEmpty
|
||||
onClick={() => {
|
||||
setEditMode(false);
|
||||
setIsReplacing(false);
|
||||
setIsDirty(false);
|
||||
onChange(valueOnFirstRender.current);
|
||||
}}
|
||||
|
@ -455,12 +463,12 @@ function SecretInputField({
|
|||
return (
|
||||
<EuiFlexGroup direction="column" gutterSize="s" alignItems="flexStart">
|
||||
<EuiFlexItem grow={false} style={{ width: '100%' }}>
|
||||
{field}
|
||||
{inputComponent}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>{cancelButton}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
|
||||
return field;
|
||||
return inputComponent;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -221,13 +221,15 @@ export async function extractAndWriteSecrets(opts: {
|
|||
return { packagePolicy, secretReferences: [] };
|
||||
}
|
||||
|
||||
const secretsToCreate = secretPaths.filter((secretPath) => !!secretPath.value.value);
|
||||
|
||||
const secrets = await createSecrets({
|
||||
esClient,
|
||||
values: secretPaths.map((secretPath) => secretPath.value.value),
|
||||
values: secretsToCreate.map((secretPath) => secretPath.value.value),
|
||||
});
|
||||
|
||||
const policyWithSecretRefs = JSON.parse(JSON.stringify(packagePolicy));
|
||||
secretPaths.forEach((secretPath, i) => {
|
||||
secretsToCreate.forEach((secretPath, i) => {
|
||||
set(policyWithSecretRefs, secretPath.path + '.value', toVarSecretRef(secrets[i].id));
|
||||
});
|
||||
|
||||
|
@ -278,7 +280,7 @@ export async function extractAndUpdateSecrets(opts: {
|
|||
// check if the previous secret is actually a secret refrerence
|
||||
// it may be that secrets were not enabled at the time of creation
|
||||
// in which case they are just stored as plain text
|
||||
if (secretPath.value.value.isSecretRef) {
|
||||
if (secretPath.value.value?.isSecretRef) {
|
||||
secretsToDelete.push({ id: secretPath.value.value.id });
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue