[8.11] [Fleet] Improve UX for policy secrets (#171405) (#172098)

# Backport

This will backport the following commits from `main` to `8.11`:
- [[Fleet] Improve UX for policy secrets
(#171405)](https://github.com/elastic/kibana/pull/171405)

<!--- 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-16T19:35:19Z","message":"[Fleet]
Improve UX for policy secrets (#171405)\n\n## Summary\r\n\r\nCloses
https://github.com/elastic/kibana/issues/171225\r\n\r\n- Highlights
secrets during package policy creation with a distinct\r\nbackground and
icon\r\n- Add tooltip + docs link for secrets where appropriate\r\n-
Detect \"new secrets\" during policy upgrade and alert the user in
a\r\nseparate callout\r\n\r\n## To do\r\n- [x] Fix any failing
tests\r\n- [x] Add tests for \"new secrets\" detection logic\r\n\r\n##
Screenshots\r\n\r\n\r\n![image](6cceb4cd-0b8e-42cd-aafb-d2e3ddcd23a8)\r\n\r\n##
How to test\r\n\r\nThere's probably an easier way to do this, but this
is what I did\r\n\r\n1. Clone
https://github.com/elastic/package-registry
and\r\nhttps://github.com/elastic/integrations\r\n2. Add the following
to `config.yml` in your package-registry
repo\r\n\r\n```yml\r\npackage_paths:\r\n -
path/to/your/integrations/build/packages\r\n```\r\n\r\n3. Build a
version of an integration with some `secrets: true` for\r\nvarious
variables. I used `1password`\r\n\r\n```shell\r\ncd
integrations/packages/1password\r\n# Edit `manifest.yml` or a given
`data_stream/*/manifest.yml` file to change some variables to `secret:
true`. Also bump the version and update
`changelog.yml`\r\nelastic-package build\r\n```\r\n\r\n4. Run the local
package registry e.g. \r\n\r\n```shell\r\ncd package-registry\r\ngo run
. --feature-proxy-mode=true -proxy-to=https://epr.elastic.co # makes it
so you can still see EPR packages in Kibana\r\n```\r\n\r\n5. Update your
`kibana.dev.yml` to point at your local package
registry\r\n\r\n```yml\r\nxpack.fleet.registryUrl:
http://localhost:8080\r\n```\r\n\r\n6. Start Kibana and Elasticsearch
and install, upgrade, etc your package\r\nin question to verify the
changes\r\n\r\n---------\r\n\r\nCo-authored-by: David Kilfoyle
<41695641+kilfoyle@users.noreply.github.com>","sha":"9396ef3d6bed213b681970a4914eeb558a30ed44","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Team:Fleet","backport:prev-minor","v8.12.0"],"number":171405,"url":"https://github.com/elastic/kibana/pull/171405","mergeCommit":{"message":"[Fleet]
Improve UX for policy secrets (#171405)\n\n## Summary\r\n\r\nCloses
https://github.com/elastic/kibana/issues/171225\r\n\r\n- Highlights
secrets during package policy creation with a distinct\r\nbackground and
icon\r\n- Add tooltip + docs link for secrets where appropriate\r\n-
Detect \"new secrets\" during policy upgrade and alert the user in
a\r\nseparate callout\r\n\r\n## To do\r\n- [x] Fix any failing
tests\r\n- [x] Add tests for \"new secrets\" detection logic\r\n\r\n##
Screenshots\r\n\r\n\r\n![image](6cceb4cd-0b8e-42cd-aafb-d2e3ddcd23a8)\r\n\r\n##
How to test\r\n\r\nThere's probably an easier way to do this, but this
is what I did\r\n\r\n1. Clone
https://github.com/elastic/package-registry
and\r\nhttps://github.com/elastic/integrations\r\n2. Add the following
to `config.yml` in your package-registry
repo\r\n\r\n```yml\r\npackage_paths:\r\n -
path/to/your/integrations/build/packages\r\n```\r\n\r\n3. Build a
version of an integration with some `secrets: true` for\r\nvarious
variables. I used `1password`\r\n\r\n```shell\r\ncd
integrations/packages/1password\r\n# Edit `manifest.yml` or a given
`data_stream/*/manifest.yml` file to change some variables to `secret:
true`. Also bump the version and update
`changelog.yml`\r\nelastic-package build\r\n```\r\n\r\n4. Run the local
package registry e.g. \r\n\r\n```shell\r\ncd package-registry\r\ngo run
. --feature-proxy-mode=true -proxy-to=https://epr.elastic.co # makes it
so you can still see EPR packages in Kibana\r\n```\r\n\r\n5. Update your
`kibana.dev.yml` to point at your local package
registry\r\n\r\n```yml\r\nxpack.fleet.registryUrl:
http://localhost:8080\r\n```\r\n\r\n6. Start Kibana and Elasticsearch
and install, upgrade, etc your package\r\nin question to verify the
changes\r\n\r\n---------\r\n\r\nCo-authored-by: David Kilfoyle
<41695641+kilfoyle@users.noreply.github.com>","sha":"9396ef3d6bed213b681970a4914eeb558a30ed44"}},"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/171405","number":171405,"mergeCommit":{"message":"[Fleet]
Improve UX for policy secrets (#171405)\n\n## Summary\r\n\r\nCloses
https://github.com/elastic/kibana/issues/171225\r\n\r\n- Highlights
secrets during package policy creation with a distinct\r\nbackground and
icon\r\n- Add tooltip + docs link for secrets where appropriate\r\n-
Detect \"new secrets\" during policy upgrade and alert the user in
a\r\nseparate callout\r\n\r\n## To do\r\n- [x] Fix any failing
tests\r\n- [x] Add tests for \"new secrets\" detection logic\r\n\r\n##
Screenshots\r\n\r\n\r\n![image](6cceb4cd-0b8e-42cd-aafb-d2e3ddcd23a8)\r\n\r\n##
How to test\r\n\r\nThere's probably an easier way to do this, but this
is what I did\r\n\r\n1. Clone
https://github.com/elastic/package-registry
and\r\nhttps://github.com/elastic/integrations\r\n2. Add the following
to `config.yml` in your package-registry
repo\r\n\r\n```yml\r\npackage_paths:\r\n -
path/to/your/integrations/build/packages\r\n```\r\n\r\n3. Build a
version of an integration with some `secrets: true` for\r\nvarious
variables. I used `1password`\r\n\r\n```shell\r\ncd
integrations/packages/1password\r\n# Edit `manifest.yml` or a given
`data_stream/*/manifest.yml` file to change some variables to `secret:
true`. Also bump the version and update
`changelog.yml`\r\nelastic-package build\r\n```\r\n\r\n4. Run the local
package registry e.g. \r\n\r\n```shell\r\ncd package-registry\r\ngo run
. --feature-proxy-mode=true -proxy-to=https://epr.elastic.co # makes it
so you can still see EPR packages in Kibana\r\n```\r\n\r\n5. Update your
`kibana.dev.yml` to point at your local package
registry\r\n\r\n```yml\r\nxpack.fleet.registryUrl:
http://localhost:8080\r\n```\r\n\r\n6. Start Kibana and Elasticsearch
and install, upgrade, etc your package\r\nin question to verify the
changes\r\n\r\n---------\r\n\r\nCo-authored-by: David Kilfoyle
<41695641+kilfoyle@users.noreply.github.com>","sha":"9396ef3d6bed213b681970a4914eeb558a30ed44"}}]}]
BACKPORT-->

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Kyle Pollich 2023-11-29 12:01:08 -05:00 committed by GitHub
parent 05a2b882bb
commit 279c469047
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 427 additions and 57 deletions

View file

@ -767,6 +767,9 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
agentPolicy: `${FLEET_DOCS}agent-policy.html`,
api: `${FLEET_DOCS}fleet-api-docs.html`,
uninstallAgent: `${SECURITY_SOLUTION_DOCS}uninstall-agent.html`,
installAndUninstallIntegrationAssets: `${FLEET_DOCS}install-uninstall-integration-assets.html`,
elasticAgentInputConfiguration: `${FLEET_DOCS}elastic-agent-input-configuration.html`,
policySecrets: `${FLEET_DOCS}agent-policy.html#agent-policy-secret-values`,
},
ecs: {
guide: `${ELASTIC_WEBSITE_URL}guide/en/ecs/current/index.html`,

View file

@ -525,6 +525,9 @@ export interface DocLinks {
agentPolicy: string;
api: string;
uninstallAgent: string;
installAndUninstallIntegrationAssets: string;
elasticAgentInputConfiguration: string;
policySecrets: string;
}>;
readonly ecs: {
readonly guide: string;

View file

@ -23,11 +23,16 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiButtonEmpty,
EuiLink,
EuiToolTip,
EuiIcon,
} from '@elastic/eui';
import styled from 'styled-components';
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
import { useStartServices } from '../../../../../../../../hooks';
import { ExperimentalFeaturesService } from '../../../../../../services';
import { DATASET_VAR_NAME } from '../../../../../../../../../common/constants';
@ -41,6 +46,16 @@ const FixedHeightDiv = styled.div`
height: 300px;
`;
const FormRow = styled(EuiFormRow)`
.euiFormRow__label {
flex: 1;
}
.euiFormRow__fieldWrapper > .euiPanel {
padding: ${(props) => props.theme.eui.euiSizeXS};
}
`;
interface InputFieldProps {
varDef: RegistryVarsEntry;
value: any;
@ -125,11 +140,11 @@ export const PackagePolicyInputVarField: React.FunctionComponent<InputFieldProps
});
}
return (
<EuiFormRow
const formRow = (
<FormRow
isInvalid={isInvalid}
error={errors}
label={fieldLabel}
label={varDef.secret ? <SecretFieldLabel fieldLabel={fieldLabel} /> : fieldLabel}
labelAppend={
isOptional ? (
<EuiText size="xs" color="subdued">
@ -138,13 +153,16 @@ export const PackagePolicyInputVarField: React.FunctionComponent<InputFieldProps
defaultMessage="Optional"
/>
</EuiText>
) : null
) : undefined
}
helpText={description && <ReactMarkdown children={description} />}
fullWidth
>
{field}
</EuiFormRow>
</FormRow>
);
return varDef.secret ? <SecretFieldWrapper>{formRow}</SecretFieldWrapper> : formRow;
}
);
@ -296,6 +314,53 @@ function getInputComponent({
}
}
const SecretFieldWrapper = ({ children }: { children: React.ReactNode }) => {
const { docLinks } = useStartServices();
return (
<EuiPanel hasShadow={false} color="subdued" paddingSize="m">
{children}
<EuiSpacer size="l" />
<EuiText size="xs">
<EuiLink href={docLinks.links.fleet.policySecrets} target="_blank">
<FormattedMessage
id="xpack.fleet.createPackagePolicy.stepConfigure.secretLearnMoreText"
defaultMessage="Learn more about policy secrets."
/>
</EuiLink>
</EuiText>
</EuiPanel>
);
};
const SecretFieldLabel = ({ fieldLabel }: { fieldLabel: string }) => {
return (
<>
<EuiFlexGroup alignItems="center" gutterSize="xs">
<EuiFlexItem grow={true} aria-label={fieldLabel}>
{fieldLabel}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiToolTip
content={
<FormattedMessage
id="xpack.fleet.createPackagePolicy.stepConfigure.secretLearnMorePopoverContent"
defaultMessage="This value is a secret. After you save this integration policy, you won't be able to view the value again."
/>
}
>
<EuiIcon aria-label="Secret value" type="questionInCircle" color="subdued" />
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="s" />
</>
);
};
function SecretInputField({
varDef,
value,
@ -313,10 +378,12 @@ function SecretInputField({
}: InputComponentProps) {
const [editMode, setEditMode] = useState(isEditPage && !value);
const valueOnFirstRender = useRef(value);
const lowercaseTitle = varDef.title?.toLowerCase();
if (isEditPage && !editMode) {
return (
<EuiPanel color="subdued" borderRadius="none" hasShadow={false}>
<>
<EuiText size="s" color="subdued">
<FormattedMessage
id="xpack.fleet.editPackagePolicy.stepConfigure.fieldSecretValueSet"
@ -342,7 +409,7 @@ function SecretInputField({
}}
/>
</EuiButtonEmpty>
</EuiPanel>
</>
);
}

View file

@ -24,10 +24,18 @@ import {
EuiFlyoutBody,
EuiFlyoutHeader,
EuiTitle,
EuiSpacer,
} from '@elastic/eui';
import styled from 'styled-components';
import type {
DryRunPackagePolicy,
PackagePolicy,
RegistryVarsEntry,
} from '../../../../../../../common';
import type { UpgradePackagePolicyDryRunResponse } from '../../../../../../../common/types/rest_spec';
import { useStartServices } from '../../../../hooks';
const FlyoutBody = styled(EuiFlyoutBody)`
.euiFlyoutBody__overflowContent {
@ -35,18 +43,125 @@ const FlyoutBody = styled(EuiFlyoutBody)`
}
`;
const HasNewSecretsCallOut = ({ newSecrets }: { newSecrets: RegistryVarsEntry[] }) => {
const { docLinks } = useStartServices();
return (
<EuiCallOut
title={i18n.translate('xpack.fleet.upgradePackagePolicy.statusCallOut.hasNewSecretsTitle', {
defaultMessage: 'New secrets added',
})}
color="primary"
iconType="iInCircle"
>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.hasNewSecrets"
defaultMessage="Some of this integration's form fields have been converted to secrets in this version. Your existing values are autofilled in each secret input during this upgrade, but you won't be able to view them again after saving. {learnMoreLink}"
values={{
learnMoreLink: (
<EuiLink href={docLinks.links.fleet.policySecrets} target="_blank">
Learn more.
</EuiLink>
),
}}
/>
<EuiSpacer size="s" />
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.hasNewSecretsList"
defaultMessage="New secrets: {secrets}"
values={{
secrets: (
<ul>
{newSecrets.map((secret) => (
<li key={secret.title}>{secret.title}</li>
))}
</ul>
),
}}
/>
</EuiCallOut>
);
};
const HasConflictsCallout = ({
currentPackagePolicy,
proposedUpgradePackagePolicy,
onPreviousConfigurationClick,
}: {
currentPackagePolicy?: PackagePolicy;
proposedUpgradePackagePolicy?: DryRunPackagePolicy;
onPreviousConfigurationClick?: () => void;
}) => {
return (
<EuiCallOut
title={i18n.translate('xpack.fleet.upgradePackagePolicy.statusCallOut.errorTitle', {
defaultMessage: 'Review field conflicts',
})}
color="warning"
iconType="warning"
>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.errorContent"
defaultMessage="This integration has conflicting fields from version {currentVersion} to {upgradeVersion} Review the configuration and save to perform the upgrade. You may reference your {previousConfigurationLink} for comparison."
values={{
currentVersion: currentPackagePolicy?.package?.version,
upgradeVersion: proposedUpgradePackagePolicy?.package?.version,
previousConfigurationLink: (
<EuiLink onClick={onPreviousConfigurationClick}>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.previousConfigurationLink"
defaultMessage="previous configuration"
/>
</EuiLink>
),
}}
/>
</EuiCallOut>
);
};
const ReadyToUpgradeCallOut = ({
currentPackagePolicy,
proposedUpgradePackagePolicy,
}: {
currentPackagePolicy?: PackagePolicy;
proposedUpgradePackagePolicy?: DryRunPackagePolicy;
}) => {
return (
<EuiCallOut
title={i18n.translate('xpack.fleet.upgradePackagePolicy.statusCallOut.successTitle', {
defaultMessage: 'Ready to upgrade',
})}
color="success"
iconType="checkInCircleFilled"
>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.successContent"
defaultMessage="This integration is ready to be upgraded from version {currentVersion} to {upgradeVersion}. Review the changes below and save to upgrade."
values={{
currentVersion: currentPackagePolicy?.package?.version,
upgradeVersion: proposedUpgradePackagePolicy?.package?.version,
}}
/>
</EuiCallOut>
);
};
export const UpgradeStatusCallout: React.FunctionComponent<{
dryRunData: UpgradePackagePolicyDryRunResponse;
}> = ({ dryRunData }) => {
newSecrets: RegistryVarsEntry[];
}> = ({ dryRunData, newSecrets }) => {
const [isPreviousVersionFlyoutOpen, setIsPreviousVersionFlyoutOpen] = useState<boolean>(false);
if (!dryRunData) {
return null;
}
const isReadyForUpgrade = !dryRunData[0].hasErrors;
const hasNewSecrets = newSecrets.length > 0;
const [currentPackagePolicy, proposedUpgradePackagePolicy] = dryRunData[0].diff || [];
const isReadyForUpgrade = currentPackagePolicy && !dryRunData[0].hasErrors;
return (
<>
@ -73,48 +188,23 @@ export const UpgradeStatusCallout: React.FunctionComponent<{
</EuiPortal>
)}
{isReadyForUpgrade && currentPackagePolicy ? (
<EuiCallOut
title={i18n.translate('xpack.fleet.upgradePackagePolicy.statusCallOut.successTitle', {
defaultMessage: 'Ready to upgrade',
})}
color="success"
iconType="checkInCircleFilled"
>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.successContent"
defaultMessage="This integration is ready to be upgraded from version {currentVersion} to {upgradeVersion}. Review the changes below and save to upgrade."
values={{
currentVersion: currentPackagePolicy?.package?.version,
upgradeVersion: proposedUpgradePackagePolicy?.package?.version,
}}
/>
</EuiCallOut>
{isReadyForUpgrade ? (
<ReadyToUpgradeCallOut
currentPackagePolicy={currentPackagePolicy}
proposedUpgradePackagePolicy={proposedUpgradePackagePolicy}
/>
) : (
<EuiCallOut
title={i18n.translate('xpack.fleet.upgradePackagePolicy.statusCallOut.errorTitle', {
defaultMessage: 'Review field conflicts',
})}
color="warning"
iconType="warning"
>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.errorContent"
defaultMessage="This integration has conflicting fields from version {currentVersion} to {upgradeVersion} Review the configuration and save to perform the upgrade. You may reference your {previousConfigurationLink} for comparison."
values={{
currentVersion: currentPackagePolicy?.package?.version,
upgradeVersion: proposedUpgradePackagePolicy?.package?.version,
previousConfigurationLink: (
<EuiLink onClick={() => setIsPreviousVersionFlyoutOpen(true)}>
<FormattedMessage
id="xpack.fleet.upgradePackagePolicy.statusCallout.previousConfigurationLink"
defaultMessage="previous configuration"
/>
</EuiLink>
),
}}
/>
</EuiCallOut>
<HasConflictsCallout
currentPackagePolicy={currentPackagePolicy}
proposedUpgradePackagePolicy={proposedUpgradePackagePolicy}
onPreviousConfigurationClick={() => setIsPreviousVersionFlyoutOpen(true)}
/>
)}
{hasNewSecrets && (
<>
<EuiSpacer size="m" />
<HasNewSecretsCallOut newSecrets={newSecrets} />
</>
)}
</>
);

View file

@ -99,7 +99,9 @@ export function usePackagePolicyWithRelatedData(
policy: { elasticsearch, ...restPackagePolicy },
} = await prepareInputPackagePolicyDataset(packagePolicy);
const result = await sendUpdatePackagePolicy(packagePolicyId, restPackagePolicy);
setFormState('SUBMITTED');
return result;
};
// Update package policy validation

View file

@ -19,7 +19,6 @@ import {
EuiErrorBoundary,
} from '@elastic/eui';
import type { PackageInfo } from '../../../types';
import {
useLink,
useBreadcrumbs,
@ -55,6 +54,7 @@ import { generateUpdatePackagePolicyDevToolsRequest } from '../services';
import { UpgradeStatusCallout } from './components';
import { usePackagePolicyWithRelatedData, useHistoryBlock } from './hooks';
import { getNewSecrets } from './utils';
export const EditPackagePolicyPage = memo(() => {
const {
@ -91,7 +91,6 @@ export const EditPackagePolicyForm = memo<{
} = useConfig();
const { getHref } = useLink();
const [] = useState<PackageInfo>();
const {
// data
agentPolicy,
@ -117,6 +116,14 @@ export const EditPackagePolicyForm = memo<{
const canWriteIntegrationPolicies = useAuthz().integrations.writeIntegrationPolicies;
const newSecrets = useMemo(() => {
if (!packageInfo) {
return [];
}
return getNewSecrets({ packageInfo, packagePolicy });
}, [packageInfo, packagePolicy]);
const policyId = agentPolicy?.id ?? '';
// Retrieve agent count
@ -418,7 +425,7 @@ export const EditPackagePolicyForm = memo<{
)}
{isUpgrade && upgradeDryRunData && (
<>
<UpgradeStatusCallout dryRunData={upgradeDryRunData} />
<UpgradeStatusCallout dryRunData={upgradeDryRunData} newSecrets={newSecrets} />
<EuiSpacer size="xxl" />
</>
)}

View file

@ -0,0 +1,143 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { PackageInfo, UpdatePackagePolicy } from '../../../../types';
import { getNewSecrets } from './get_new_secrets';
describe('getNewSecrets', () => {
it('does not find new secrets when there are no secrets configured', () => {
const packageInfo = {
name: 'mock-package',
title: 'Mock package',
version: '0.0.0',
vars: [
{
name: 'package-var',
type: 'string',
secret: false,
},
],
policy_templates: [
{
name: 'test-policy-template',
inputs: [
{
type: 'test-input',
title: 'Test input',
description: 'Test input',
vars: [
{
name: 'policy-template-var',
type: 'string',
secret: false,
},
],
},
],
},
],
} as unknown as PackageInfo;
const packagePolicy = {
vars: [
{
name: 'package-var',
value: 'test',
},
],
inputs: [
{
name: 'test-input',
vars: {
'policy-template-var': {
value: 'test',
},
},
},
],
} as unknown as UpdatePackagePolicy;
expect(
getNewSecrets({
packageInfo,
packagePolicy,
})
).toEqual([]);
});
it('finds new secrets when they exist', () => {
const packageInfo = {
name: 'mock-package',
title: 'Mock package',
version: '0.0.0',
vars: [
{
name: 'package-var',
type: 'string',
secret: true,
},
],
policy_templates: [
{
name: 'test-policy-template',
inputs: [
{
type: 'test-input',
title: 'Test input',
description: 'Test input',
vars: [
{
name: 'policy-template-var',
type: 'string',
secret: true,
},
],
},
],
},
],
} as unknown as PackageInfo;
const packagePolicy = {
vars: [
{
name: 'package-var',
value: 'test',
},
],
inputs: [
{
name: 'test-input',
vars: {
'policy-template-var': {
value: 'test',
},
},
},
],
} as unknown as UpdatePackagePolicy;
expect(
getNewSecrets({
packageInfo,
packagePolicy,
})
).toEqual([
{
name: 'package-var',
secret: true,
type: 'string',
},
{
name: 'policy-template-var',
secret: true,
type: 'string',
},
]);
});
});

View file

@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { isInputOnlyPolicyTemplate } from '../../../../../../../common/services';
import type { PackageInfo, UpdatePackagePolicy } from '../../../../types';
export const getNewSecrets = ({
packageInfo,
packagePolicy,
}: {
packageInfo: PackageInfo;
packagePolicy: UpdatePackagePolicy;
}) => {
const result = [];
for (const packageVar of packageInfo.vars ?? []) {
const isVarSecretOnPolicy = packagePolicy.vars?.[packageVar.name]?.value?.isSecretRef;
if (packageVar.secret && !isVarSecretOnPolicy) {
result.push(packageVar);
}
}
for (const policyTemplate of packageInfo.policy_templates ?? []) {
if (isInputOnlyPolicyTemplate(policyTemplate)) {
for (const packageVar of policyTemplate.vars ?? []) {
const isVarSecretOnPolicy =
packagePolicy.inputs?.[0]?.vars?.[packageVar.name]?.value?.isSecretRef;
if (packageVar.secret && !isVarSecretOnPolicy) {
result.push(packageVar);
}
}
} else {
for (const input of policyTemplate.inputs ?? []) {
for (const packageVar of input.vars ?? []) {
const isVarSecretOnPolicy =
packagePolicy.inputs?.[0]?.vars?.[packageVar.name]?.value?.isSecretRef;
if (packageVar.secret && !isVarSecretOnPolicy) {
result.push(packageVar);
}
}
}
}
}
return result;
};

View file

@ -7,3 +7,4 @@
export * from './has_upgrade_available';
export { fixApmDurationVars } from './fix_apm_duration_vars';
export * from './get_new_secrets';

View file

@ -43728,10 +43728,10 @@
"observabilityAlertDetails.alertThresholdTimeRangeRect.detailsTooltip": "Seuil",
"randomSampling.ui.sliderControl.accuracyLabel": "Précision",
"randomSampling.ui.sliderControl.performanceLabel": "Performances",
"reactPackages.mountPointPortal.errorMessage": "Erreur lors du rendu du contenu du portail.",
"reporting.common.browserCouldNotLaunchErrorMessage": "Impossible de générer des captures d'écran, car le navigateur ne sest pas lancé. Consultez les logs de serveur pour en savoir plus.",
"reporting.common.cloud.insufficientSystemMemoryError": "Impossible de générer ce rapport en raison dun manque de mémoire.",
"reporting.common.pdfWorkerOutOfMemoryErrorMessage": "Impossible de générer un PDF en raison dun manque de mémoire. Essayez de réduire la taille du PDF et relancez ce rapport.",
"reactPackages.mountPointPortal.errorMessage": "Erreur lors du rendu du contenu du portail.",
"savedObjectsFinder.advancedSettings.listingLimitText": "Nombre d'objets à récupérer pour les pages de listing",
"savedObjectsFinder.advancedSettings.listingLimitTitle": "Limite de listing dobjets",
"savedObjectsFinder.advancedSettings.perPageText": "Nombre d'objets à afficher par page dans la boîte de dialogue de chargement",

View file

@ -43718,10 +43718,10 @@
"observabilityAlertDetails.alertThresholdTimeRangeRect.detailsTooltip": "しきい値",
"randomSampling.ui.sliderControl.accuracyLabel": "精度",
"randomSampling.ui.sliderControl.performanceLabel": "パフォーマンス",
"reactPackages.mountPointPortal.errorMessage": "ポータルコンテンツのレンダリングエラー",
"reporting.common.browserCouldNotLaunchErrorMessage": "ブラウザーが起動していないため、スクリーンショットを生成できません。詳細については、サーバーログを参照してください。",
"reporting.common.cloud.insufficientSystemMemoryError": "メモリ不足のため、このレポートを生成できません。",
"reporting.common.pdfWorkerOutOfMemoryErrorMessage": "メモリ不足のため、PDFを生成できません。PDFのサイズを小さくして、このレポートを再試行してください。",
"reactPackages.mountPointPortal.errorMessage": "ポータルコンテンツのレンダリングエラー",
"savedObjectsFinder.advancedSettings.listingLimitText": "一覧ページ用に取得するオブジェクトの数です",
"savedObjectsFinder.advancedSettings.listingLimitTitle": "オブジェクト取得制限",
"savedObjectsFinder.advancedSettings.perPageText": "読み込みダイアログで表示されるページごとのオブジェクトの数です",

View file

@ -43712,10 +43712,10 @@
"observabilityAlertDetails.alertThresholdTimeRangeRect.detailsTooltip": "阈值",
"randomSampling.ui.sliderControl.accuracyLabel": "准确性",
"randomSampling.ui.sliderControl.performanceLabel": "性能",
"reactPackages.mountPointPortal.errorMessage": "呈现门户内容时出错",
"reporting.common.browserCouldNotLaunchErrorMessage": "无法生成屏幕截图,因为浏览器未启动。有关更多信息,请查看服务器日志。",
"reporting.common.cloud.insufficientSystemMemoryError": "由于内存不足,无法生成此报告。",
"reporting.common.pdfWorkerOutOfMemoryErrorMessage": "由于内存不足,无法生成 PDF。尝试生成更小的 PDF然后重试此报告。",
"reactPackages.mountPointPortal.errorMessage": "呈现门户内容时出错",
"savedObjectsFinder.advancedSettings.listingLimitText": "要为列表页面提取的对象数目",
"savedObjectsFinder.advancedSettings.listingLimitTitle": "对象列表限制",
"savedObjectsFinder.advancedSettings.perPageText": "加载对话框中每页要显示的对象数目",