Adds popover text for Inventory and InventorySources

This commit is contained in:
Alex Corey 2022-05-09 10:40:36 -04:00
parent f7be6b6423
commit 33df2e8aa4
16 changed files with 336 additions and 417 deletions

View File

@ -154,7 +154,7 @@ VariablesDetail.propTypes = {
label: node.isRequired,
rows: oneOfType([number, string]),
dataCy: string,
helpText: string,
helpText: oneOfType([node, string]),
name: string.isRequired,
};
VariablesDetail.defaultProps = {

View File

@ -16,10 +16,10 @@ import { InventoriesAPI } from 'api';
import useRequest, { useDismissableError } from 'hooks/useRequest';
import { Inventory } from 'types';
import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails';
import helpText from '../shared/Inventory.helptext';
function InventoryDetail({ inventory }) {
const history = useHistory();
const {
result: instanceGroups,
isLoading,
@ -106,6 +106,7 @@ function InventoryDetail({ inventory }) {
inventory.summary_fields.labels?.results?.length > 0 && (
<Detail
fullWidth
helpText={helpText.labels}
label={t`Labels`}
value={
<ChipGroup
@ -123,6 +124,7 @@ function InventoryDetail({ inventory }) {
)}
<VariablesDetail
label={t`Variables`}
helpText={helpText.variables()}
value={inventory.variables}
rows={4}
name="variables"

View File

@ -9,6 +9,8 @@ import {
TextListItemVariants,
Tooltip,
} from '@patternfly/react-core';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import AlertModal from 'components/AlertModal';
import ContentError from 'components/ContentError';
import ContentLoading from 'components/ContentLoading';
@ -26,8 +28,10 @@ import { InventorySourcesAPI } from 'api';
import { relatedResourceDeleteRequests } from 'util/getRelatedResourceDeleteDetails';
import useIsMounted from 'hooks/useIsMounted';
import { formatDateString } from 'util/dates';
import Popover from 'components/Popover';
import InventorySourceSyncButton from '../shared/InventorySourceSyncButton';
import useWsInventorySourcesDetails from '../InventorySources/useWsInventorySourcesDetails';
import helpText from '../shared/Inventory.helptext';
function InventorySourceDetail({ inventorySource }) {
const {
@ -64,6 +68,7 @@ function InventorySourceDetail({ inventorySource }) {
} = summary_fields;
const [deletionError, setDeletionError] = useState(false);
const config = useConfig();
const history = useHistory();
const isMounted = useIsMounted();
@ -82,6 +87,7 @@ function InventorySourceDetail({ inventorySource }) {
{}
);
const docsBaseUrl = getDocsBaseUrl(config);
useEffect(() => {
fetchSourceChoices();
}, [fetchSourceChoices]);
@ -123,21 +129,33 @@ function InventorySourceDetail({ inventorySource }) {
{overwrite && (
<TextListItem component={TextListItemVariants.li}>
{t`Overwrite local groups and hosts from remote inventory source`}
<Popover content={helpText.subFormOptions.overwrite} />
</TextListItem>
)}
{overwrite_vars && (
<TextListItem component={TextListItemVariants.li}>
{t`Overwrite local variables from remote inventory source`}
<Popover content={helpText.subFormOptions.overwriteVariables} />
</TextListItem>
)}
{update_on_launch && (
<TextListItem component={TextListItemVariants.li}>
{t`Update on launch`}
<Popover
content={helpText.subFormOptions.updateOnLaunch({
value: source_project,
})}
/>
</TextListItem>
)}
{update_on_project_update && (
<TextListItem component={TextListItemVariants.li}>
{t`Update on project update`}
<Popover
content={helpText.subFormOptions.updateOnProjectUpdate({
value: source_project,
})}
/>
</TextListItem>
)}
</TextList>
@ -226,17 +244,35 @@ function InventorySourceDetail({ inventorySource }) {
{source === 'scm' ? (
<Detail
label={t`Inventory file`}
helpText={helpText.sourcePath}
value={source_path === '' ? t`/ (project root)` : source_path}
/>
) : null}
<Detail label={t`Verbosity`} value={VERBOSITY[verbosity]} />
<Detail
label={t`Verbosity`}
helpText={helpText.subFormVerbosityFields}
value={VERBOSITY[verbosity]}
/>
<Detail
label={t`Cache timeout`}
value={`${update_cache_timeout} ${t`seconds`}`}
helpText={helpText.subFormOptions.cachedTimeOut}
/>
<Detail
label={t`Host Filter`}
helpText={helpText.hostFilter}
value={host_filter}
/>
<Detail
label={t`Enabled Variable`}
helpText={helpText.enabledVariableField}
value={enabled_var}
/>
<Detail
label={t`Enabled Value`}
helpText={helpText.enabledValue}
value={enabled_value}
/>
<Detail label={t`Host Filter`} value={host_filter} />
<Detail label={t`Enabled Variable`} value={enabled_var} />
<Detail label={t`Enabled Value`} value={enabled_value} />
{credentials?.length > 0 && (
<Detail
fullWidth
@ -254,6 +290,7 @@ function InventorySourceDetail({ inventorySource }) {
label={t`Source variables`}
rows={4}
value={source_vars}
helpText={helpText.sourceVars(docsBaseUrl, source)}
name="source_vars"
dataCy="inventory-source-detail-variables"
/>

View File

@ -0,0 +1,196 @@
/* eslint-disable react/destructuring-assignment */
import React from 'react';
import { t, Trans } from '@lingui/macro';
import { Link } from 'react-router-dom';
const ansibleDocUrls = {
ec2: 'https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html',
azure_rm:
'https://docs.ansible.com/ansible/latest/collections/azure/azcollection/azure_rm_inventory.html',
controller:
'https://docs.ansible.com/ansible/latest/collections/awx/awx/tower_inventory.html',
gce: 'https://docs.ansible.com/ansible/latest/collections/google/cloud/gcp_compute_inventory.html',
insights:
'https://docs.ansible.com/ansible/latest/collections/redhatinsights/insights/insights_inventory.html',
openstack:
'https://docs.ansible.com/ansible/latest/collections/openstack/cloud/openstack_inventory.html',
satellite6:
'https://docs.ansible.com/ansible/latest/collections/theforeman/foreman/foreman_inventory.html',
rhv: 'https://docs.ansible.com/ansible/latest/collections/ovirt/ovirt/ovirt_inventory.html',
vmware:
'https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_vm_inventory_inventory.html',
};
const getInventoryHelpTextStrings = {
labels: t`Optional labels that describe this inventory,
such as 'dev' or 'test'. Labels can be used to group and filter
inventories and completed jobs.`,
variables: () => {
const jsonExample = `
{
"somevar": "somevalue"
"somepassword": "Magic"
}
`;
const yamlExample = `
---
somevar: somevalue
somepassword: magic
`;
return (
<>
<Trans>
Variables must be in JSON or YAML syntax. Use the radio button to
toggle between the two.
</Trans>
<br />
<br />
<Trans>JSON:</Trans>
<pre>{jsonExample}</pre>
<br />
<Trans>YAML:</Trans>
<pre>{yamlExample}</pre>
<br />
<Trans>
View JSON examples at{' '}
<a
href="http://www.json.org"
target="_blank"
rel="noopener noreferrer"
>
www.json.org
</a>
</Trans>
<br />
<Trans>
View YAML examples at{' '}
<a
href="http://docs.ansible.com/YAMLSyntax.html"
target="_blank"
rel="noopener noreferrer"
>
docs.ansible.com
</a>
</Trans>
</>
);
},
subFormVerbosityFields: t`Control the level of output Ansible
will produce for inventory source update jobs.`,
subFormOptions: {
overwrite: (
<>
{t`If checked, any hosts and groups that were
previously present on the external source but are now removed
will be removed from the inventory. Hosts and groups
that were not managed by the inventory source will be promoted
to the next manually created group or if there is no manually
created group to promote them into, they will be left in the "all"
default group for the inventory.`}
<br />
<br />
{t`When not checked, local child
hosts and groups not found on the external source will remain
untouched by the inventory update process.`}
</>
),
overwriteVariables: (
<>
{t`If checked, all variables for child groups
and hosts will be removed and replaced by those found
on the external source.`}
<br />
<br />
{t`When not checked, a merge will be performed,
combining local variables with those found on the
external source.`}
</>
),
updateOnLaunch: ({ value }) => (
<>
<div>
{t`Each time a job runs using this inventory,
refresh the inventory from the selected source before
executing job tasks.`}
</div>
<br />
{value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${value.id}/details`}> {value.name} </Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
),
updateOnProjectUpdate: ({ value }) => (
<>
<div>
{t`After every project update where the SCM revision
changes, refresh the inventory from the selected source
before executing job tasks. This is intended for static content,
like the Ansible inventory .ini file format.`}
</div>
<br />
{value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${value.id}/details`}> {value.name} </Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
),
cachedTimeOut: t`Time in seconds to consider an inventory sync
to be current. During job runs and callbacks the task system will
evaluate the timestamp of the latest sync. If it is older than
Cache Timeout, it is not considered current, and a new
inventory sync will be performed.`,
},
enabledVariableField: t`Retrieve the enabled state from the given dict of host variables.
The enabled variable may be specified using dot notation, e.g: 'foo.bar'`,
enabledValue: t`This field is ignored unless an Enabled Variable is set. If the enabled variable matches this value, the host will be enabled on import.`,
hostFilter: t`Regular expression where only matching host names will be imported. The filter is applied as a post-processing step after any inventory plugin filters are applied.`,
sourceVars: (docsBaseUrl, source) => {
const docsUrl = `${docsBaseUrl}/html/userguide/inventories.html#inventory-plugins`;
let sourceType = '';
if (source && source !== 'scm') {
const type = ansibleDocUrls[source].split(/[/,.]/);
sourceType = type[type.length - 2];
}
return (
<>
<Trans>
Variables used to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a
href={docsBaseUrl ? docsUrl : ''}
target="_blank"
rel="noopener noreferrer"
>
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a
href={ansibleDocUrls[source]}
target="_blank"
rel="noopener noreferrer"
>
{sourceType}
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
);
},
sourcePath: t`The inventory file
to be synced by this source. You can select from
the dropdown or enter a file within the input.`,
};
export default getInventoryHelpTextStrings;

View File

@ -13,6 +13,7 @@ import InstanceGroupsLookup from 'components/Lookup/InstanceGroupsLookup';
import OrganizationLookup from 'components/Lookup/OrganizationLookup';
import ContentError from 'components/ContentError';
import { FormColumnLayout, FormFullWidthLayout } from 'components/FormLayout';
import helpText from './Inventory.helptext';
function InventoryFormFields({ inventory }) {
const [contentError, setContentError] = useState(false);
@ -72,13 +73,7 @@ function InventoryFormFields({ inventory }) {
<FormFullWidthLayout>
<FormGroup
label={t`Labels`}
labelIcon={
<Popover
content={t`Optional labels that describe this inventory,
such as 'dev' or 'test'. Labels can be used to group and filter
inventories and completed jobs.`}
/>
}
labelIcon={<Popover content={helpText.labels} />}
fieldId="inventory-labels"
>
<LabelSelect
@ -89,7 +84,7 @@ function InventoryFormFields({ inventory }) {
/>
</FormGroup>
<VariablesField
tooltip={t`Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax`}
tooltip={helpText.variables()}
id="inventory-variables"
name="variables"
label={t`Variables`}

View File

@ -1,10 +1,10 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { t } from '@lingui/macro';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import {
OptionsField,
SourceVarsField,
@ -13,6 +13,7 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const AzureSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
@ -27,12 +28,7 @@ const AzureSubForm = ({ autoPopulateCredential }) => {
},
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/azure/azcollection/azure_rm_inventory.html';
const docsBaseUrl = getDocsBaseUrl(config);
return (
<>
@ -54,24 +50,7 @@ const AzureSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
azure_rm
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(docsBaseUrl, 'azure_rm')}
/>
</>
);

View File

@ -1,11 +1,11 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { t } from '@lingui/macro';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import {
OptionsField,
VerbosityField,
@ -14,13 +14,13 @@ import {
HostFilterField,
SourceVarsField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const ControllerSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] =
useField('credential');
const config = useConfig();
const handleCredentialUpdate = useCallback(
(value) => {
setFieldValue('credential', value);
@ -29,12 +29,6 @@ const ControllerSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/awx/awx/tower_inventory.html';
return (
<>
<CredentialLookup
@ -55,24 +49,10 @@ const ControllerSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
Tower
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(
getDocsBaseUrl(config),
'controller'
)}
/>
</>
);

View File

@ -1,9 +1,9 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { t } from '@lingui/macro';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import {
OptionsField,
SourceVarsField,
@ -12,12 +12,12 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const EC2SubForm = () => {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta] = useField('credential');
const config = useConfig();
const handleCredentialUpdate = useCallback(
(value) => {
setFieldValue('credential', value);
@ -25,12 +25,7 @@ const EC2SubForm = () => {
},
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/amazon/aws/aws_ec2_inventory.html';
const docsBaseUrl = getDocsBaseUrl(config);
return (
<>
@ -48,24 +43,7 @@ const EC2SubForm = () => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
aws_ec2
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(docsBaseUrl, 'ec2')}
/>
</>
);

View File

@ -1,10 +1,10 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { t } from '@lingui/macro';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import {
OptionsField,
VerbosityField,
@ -13,13 +13,13 @@ import {
HostFilterField,
SourceVarsField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const GCESubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] =
useField('credential');
const config = useConfig();
const handleCredentialUpdate = useCallback(
(value) => {
setFieldValue('credential', value);
@ -27,12 +27,7 @@ const GCESubForm = ({ autoPopulateCredential }) => {
},
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/google/cloud/gcp_compute_inventory.html';
const docsBaseUrl = getDocsBaseUrl(config);
return (
<>
@ -54,24 +49,7 @@ const GCESubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
gcp_compute
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(docsBaseUrl, 'gce')}
/>
</>
);

View File

@ -1,11 +1,11 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import { t } from '@lingui/macro';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import {
OptionsField,
VerbosityField,
@ -14,13 +14,13 @@ import {
HostFilterField,
SourceVarsField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const InsightsSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] =
useField('credential');
const config = useConfig();
const handleCredentialUpdate = useCallback(
(value) => {
setFieldValue('credential', value);
@ -28,12 +28,7 @@ const InsightsSubForm = ({ autoPopulateCredential }) => {
},
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/redhatinsights/insights/insights_inventory.html';
const docsBaseUrl = getDocsBaseUrl(config);
return (
<>
@ -55,24 +50,7 @@ const InsightsSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
Insights
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(docsBaseUrl, 'insights')}
/>
</>
);

View File

@ -1,10 +1,10 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import {
OptionsField,
SourceVarsField,
@ -13,6 +13,7 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const OpenStackSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
@ -28,12 +29,6 @@ const OpenStackSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/openstack/cloud/openstack_inventory.html';
return (
<>
<CredentialLookup
@ -54,24 +49,10 @@ const OpenStackSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
openstack
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(
getDocsBaseUrl(config),
'openstack'
)}
/>
</>
);

View File

@ -21,12 +21,14 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const SCMSubForm = ({ autoPopulateProject }) => {
const [isOpen, setIsOpen] = useState(false);
const [sourcePath, setSourcePath] = useState([]);
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField] = useField('credential');
const [projectField, projectMeta, projectHelpers] =
useField('source_project');
const [sourcePathField, sourcePathMeta, sourcePathHelpers] = useField({
@ -104,13 +106,7 @@ const SCMSubForm = ({ autoPopulateProject }) => {
}
isRequired
label={t`Inventory file`}
labelIcon={
<Popover
content={t`Select the inventory file
to be synced by this source. You can select from
the dropdown or enter a file within the input.`}
/>
}
labelIcon={<Popover content={helpText.sourcePath} />}
>
<Select
ouiaId="InventorySourceForm-source_path"

View File

@ -1,10 +1,10 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import {
OptionsField,
SourceVarsField,
@ -13,13 +13,13 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const SatelliteSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] =
useField('credential');
const config = useConfig();
const handleCredentialUpdate = useCallback(
(value) => {
setFieldValue('credential', value);
@ -28,12 +28,6 @@ const SatelliteSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/theforeman/foreman/foreman_inventory.html';
return (
<>
<CredentialLookup
@ -54,24 +48,10 @@ const SatelliteSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
foreman
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(
getDocsBaseUrl(config),
'satellite6'
)}
/>
</>
);

View File

@ -1,8 +1,7 @@
import React, { useEffect } from 'react';
import { t, Trans } from '@lingui/macro';
import { t } from '@lingui/macro';
import { useField } from 'formik';
import { Link } from 'react-router-dom';
import { FormGroup } from '@patternfly/react-core';
import { minMaxValue, regExp } from 'util/validators';
import AnsibleSelect from 'components/AnsibleSelect';
@ -10,67 +9,23 @@ import { VariablesField } from 'components/CodeEditor';
import FormField, { CheckboxField } from 'components/FormField';
import { FormFullWidthLayout, FormCheckboxLayout } from 'components/FormLayout';
import Popover from 'components/Popover';
import helpText from '../Inventory.helptext';
export const SourceVarsField = ({ popoverContent }) => {
const jsonExample = `
{
"somevar": "somevalue"
"somepassword": "Magic"
}
`;
const yamlExample = `
---
somevar: somevalue
somepassword: magic
`;
return (
<FormFullWidthLayout>
<VariablesField
id="source_vars"
name="source_vars"
label={t`Source variables`}
tooltip={
<div>
{popoverContent}
<Trans>
Enter variables using either JSON or YAML syntax. Use the radio
button to toggle between the two.
</Trans>
<br />
<br />
<Trans>JSON:</Trans>
<pre>{jsonExample}</pre>
<br />
<Trans>YAML:</Trans>
<pre>{yamlExample}</pre>
<br />
<Trans>
View JSON examples at{' '}
<a
href="http://www.json.org"
target="_blank"
rel="noopener noreferrer"
>
www.json.org
</a>
</Trans>
<br />
<Trans>
View YAML examples at{' '}
<a
href="http://docs.ansible.com/YAMLSyntax.html"
target="_blank"
rel="noopener noreferrer"
>
docs.ansible.com
</a>
</Trans>
</div>
}
/>
</FormFullWidthLayout>
);
};
export const SourceVarsField = ({ popoverContent }) => (
<FormFullWidthLayout>
<VariablesField
id="source_vars"
name="source_vars"
label={t`Source variables`}
tooltip={
<>
{popoverContent}
{helpText.variables()}
</>
}
/>
</FormFullWidthLayout>
);
export const VerbosityField = () => {
const [field, meta, helpers] = useField('verbosity');
@ -80,17 +35,13 @@ export const VerbosityField = () => {
{ value: '1', key: '1', label: t`1 (Info)` },
{ value: '2', key: '2', label: t`2 (Debug)` },
];
return (
<FormGroup
fieldId="verbosity"
validated={isValid ? 'default' : 'error'}
label={t`Verbosity`}
labelIcon={
<Popover
content={t`Control the level of output Ansible
will produce for inventory source update jobs.`}
/>
}
labelIcon={<Popover content={helpText.subFormVerbosityFields} />}
>
<AnsibleSelect
id="verbosity"
@ -105,8 +56,8 @@ export const VerbosityField = () => {
export const OptionsField = ({ showProjectUpdate = false }) => {
const [updateOnLaunchField] = useField('update_on_launch');
const [, , updateCacheTimeoutHelper] = useField('update_cache_timeout');
const [updatedOnProjectUpdateField] = useField('update_on_project_update');
const [projectField] = useField('source_project');
const [updatedOnProjectUpdateField] = useField('update_on_project_update');
useEffect(() => {
if (!updateOnLaunchField.value) {
@ -123,66 +74,20 @@ export const OptionsField = ({ showProjectUpdate = false }) => {
id="overwrite"
name="overwrite"
label={t`Overwrite`}
tooltip={
<>
{t`If checked, any hosts and groups that were
previously present on the external source but are now removed
will be removed from the inventory. Hosts and groups
that were not managed by the inventory source will be promoted
to the next manually created group or if there is no manually
created group to promote them into, they will be left in the "all"
default group for the inventory.`}
<br />
<br />
{t`When not checked, local child
hosts and groups not found on the external source will remain
untouched by the inventory update process.`}
</>
}
tooltip={helpText.subFormOptions.overwrite}
/>
<CheckboxField
id="overwrite_vars"
name="overwrite_vars"
label={t`Overwrite variables`}
tooltip={
<>
{t`If checked, all variables for child groups
and hosts will be removed and replaced by those found
on the external source.`}
<br />
<br />
{t`When not checked, a merge will be performed,
combining local variables with those found on the
external source.`}
</>
}
tooltip={helpText.subFormOptions.overwriteVariables}
/>
<CheckboxField
isDisabled={updatedOnProjectUpdateField.value}
id="update_on_launch"
name="update_on_launch"
label={t`Update on launch`}
tooltip={
<>
<div>
{t`Each time a job runs using this inventory,
refresh the inventory from the selected source before
executing job tasks.`}
</div>
<br />
{projectField?.value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${projectField.value.id}/details`}>
{' '}
{projectField.value.name}{' '}
</Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
}
tooltip={helpText.subFormOptions.updateOnLaunch(projectField)}
/>
{showProjectUpdate && (
<CheckboxField
@ -190,28 +95,9 @@ export const OptionsField = ({ showProjectUpdate = false }) => {
id="update_on_project_update"
name="update_on_project_update"
label={t`Update on project update`}
tooltip={
<>
<div>
{t`After every project update where the SCM revision
changes, refresh the inventory from the selected source
before executing job tasks. This is intended for static content,
like the Ansible inventory .ini file format.`}
</div>
<br />
{projectField?.value && (
<div>
{t`If you want the Inventory Source to update on
launch and on project update, click on Update on launch, and also go to`}
<Link to={`/projects/${projectField.value.id}/details`}>
{' '}
{projectField.value.name}{' '}
</Link>
{t`and click on Update Revision on Launch`}
</div>
)}
</>
}
tooltip={helpText.subFormOptions.updateOnProjectUpdate(
projectField
)}
/>
)}
</FormCheckboxLayout>
@ -226,11 +112,7 @@ export const OptionsField = ({ showProjectUpdate = false }) => {
max="2147483647"
validate={minMaxValue(0, 2147483647)}
label={t`Cache timeout (seconds)`}
tooltip={t`Time in seconds to consider an inventory sync
to be current. During job runs and callbacks the task system will
evaluate the timestamp of the latest sync. If it is older than
Cache Timeout, it is not considered current, and a new
inventory sync will be performed.`}
tooltip={helpText.cachedTimeOut}
/>
)}
</>
@ -241,8 +123,7 @@ export const EnabledVarField = () => (
<FormField
id="inventory-enabled-var"
label={t`Enabled Variable`}
tooltip={t`Retrieve the enabled state from the given dict of host variables.
The enabled variable may be specified using dot notation, e.g: 'foo.bar'`}
tooltip={helpText.enabledVariableField}
name="enabled_var"
type="text"
/>
@ -252,7 +133,7 @@ export const EnabledValueField = () => (
<FormField
id="inventory-enabled-value"
label={t`Enabled Value`}
tooltip={t`This field is ignored unless an Enabled Variable is set. If the enabled variable matches this value, the host will be enabled on import.`}
tooltip={helpText.enabledValue}
name="enabled_value"
type="text"
/>
@ -262,7 +143,7 @@ export const HostFilterField = () => (
<FormField
id="host-filter"
label={t`Host Filter`}
tooltip={t`Regular expression where only matching host names will be imported. The filter is applied as a post-processing step after any inventory plugin filters are applied.`}
tooltip={helpText.hostFilter}
name="host_filter"
type="text"
validate={regExp()}

View File

@ -1,10 +1,10 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import {
OptionsField,
SourceVarsField,
@ -13,13 +13,13 @@ import {
EnabledValueField,
HostFilterField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const VMwareSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
const [credentialField, credentialMeta, credentialHelpers] =
useField('credential');
const config = useConfig();
const handleCredentialUpdate = useCallback(
(value) => {
setFieldValue('credential', value);
@ -28,11 +28,7 @@ const VMwareSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/community/vmware/vmware_vm_inventory_inventory.html';
const docsBaseUrl = getDocsBaseUrl(config);
return (
<>
@ -54,24 +50,7 @@ const VMwareSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
vmware_vm_inventory
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(docsBaseUrl, 'vmware')}
/>
</>
);

View File

@ -1,10 +1,10 @@
import React, { useCallback } from 'react';
import { useField, useFormikContext } from 'formik';
import { t, Trans } from '@lingui/macro';
import { t } from '@lingui/macro';
import { useConfig } from 'contexts/Config';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import CredentialLookup from 'components/Lookup/CredentialLookup';
import { required } from 'util/validators';
import getDocsBaseUrl from 'util/getDocsBaseUrl';
import { useConfig } from 'contexts/Config';
import {
OptionsField,
VerbosityField,
@ -13,6 +13,7 @@ import {
HostFilterField,
SourceVarsField,
} from './SharedFields';
import helpText from '../Inventory.helptext';
const VirtualizationSubForm = ({ autoPopulateCredential }) => {
const { setFieldValue, setFieldTouched } = useFormikContext();
@ -28,12 +29,7 @@ const VirtualizationSubForm = ({ autoPopulateCredential }) => {
[setFieldValue, setFieldTouched]
);
const pluginLink = `${getDocsBaseUrl(
config
)}/html/userguide/inventories.html#inventory-plugins`;
const configLink =
'https://docs.ansible.com/ansible/latest/collections/ovirt/ovirt/ovirt_inventory.html';
const docsBaseUrl = getDocsBaseUrl(config);
return (
<>
<CredentialLookup
@ -54,24 +50,7 @@ const VirtualizationSubForm = ({ autoPopulateCredential }) => {
<EnabledValueField />
<OptionsField />
<SourceVarsField
popoverContent={
<>
<Trans>
Enter variables to configure the inventory source. For a detailed
description of how to configure this plugin, see{' '}
<a href={pluginLink} target="_blank" rel="noopener noreferrer">
Inventory Plugins
</a>{' '}
in the documentation and the{' '}
<a href={configLink} target="_blank" rel="noopener noreferrer">
ovirt
</a>{' '}
plugin configuration guide.
</Trans>
<br />
<br />
</>
}
popoverContent={helpText.sourceVars(docsBaseUrl, 'rhv')}
/>
</>
);