mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
Merge pull request #6570 from marshmalien/6530-wf-node-inv-src-details
Add Inventory Source workflow node prompt details Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
commit
646e403fbd
@ -10,6 +10,9 @@ import { VariablesDetail } from '@components/CodeMirrorInput';
|
||||
import { DetailList, Detail, UserDateDetail } from '@components/DetailList';
|
||||
|
||||
import PromptProjectDetail from './PromptProjectDetail';
|
||||
import PromptInventorySourceDetail from './PromptInventorySourceDetail';
|
||||
import PromptJobTemplateDetail from './PromptJobTemplateDetail';
|
||||
import PromptWFJobTemplateDetail from './PromptWFJobTemplateDetail';
|
||||
|
||||
const PromptHeader = styled.h2`
|
||||
font-weight: bold;
|
||||
@ -84,6 +87,15 @@ function PromptDetail({ i18n, resource, launchConfig = {} }) {
|
||||
{resource?.type === 'project' && (
|
||||
<PromptProjectDetail resource={resource} />
|
||||
)}
|
||||
{resource?.type === 'inventory_source' && (
|
||||
<PromptInventorySourceDetail resource={resource} />
|
||||
)}
|
||||
{resource?.type === 'job_template' && (
|
||||
<PromptJobTemplateDetail resource={resource} />
|
||||
)}
|
||||
{resource?.type === 'workflow_job_template' && (
|
||||
<PromptWFJobTemplateDetail resource={resource} />
|
||||
)}
|
||||
|
||||
<UserDateDetail
|
||||
label={i18n._(t`Created`)}
|
||||
|
||||
@ -0,0 +1,161 @@
|
||||
import React from 'react';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { Chip, ChipGroup, List, ListItem } from '@patternfly/react-core';
|
||||
import { Detail } from '@components/DetailList';
|
||||
import { VariablesDetail } from '@components/CodeMirrorInput';
|
||||
import CredentialChip from '@components/CredentialChip';
|
||||
|
||||
function PromptInventorySourceDetail({ i18n, resource }) {
|
||||
const {
|
||||
custom_virtualenv,
|
||||
group_by,
|
||||
instance_filters,
|
||||
overwrite,
|
||||
overwrite_vars,
|
||||
source,
|
||||
source_regions,
|
||||
source_vars,
|
||||
source_path,
|
||||
summary_fields,
|
||||
update_cache_timeout,
|
||||
update_on_launch,
|
||||
update_on_project_update,
|
||||
verbosity,
|
||||
} = resource;
|
||||
|
||||
const VERBOSITY = {
|
||||
0: i18n._(t`0 (Normal)`),
|
||||
1: i18n._(t`1 (Verbose)`),
|
||||
2: i18n._(t`2 (More Verbose)`),
|
||||
3: i18n._(t`3 (Debug)`),
|
||||
4: i18n._(t`4 (Connection Debug)`),
|
||||
};
|
||||
|
||||
let optionsList = '';
|
||||
if (
|
||||
overwrite ||
|
||||
overwrite_vars ||
|
||||
update_on_launch ||
|
||||
update_on_project_update
|
||||
) {
|
||||
optionsList = (
|
||||
<List>
|
||||
{overwrite && <ListItem>{i18n._(t`Overwrite`)}</ListItem>}
|
||||
{overwrite_vars && (
|
||||
<ListItem>{i18n._(t`Overwrite Variables`)}</ListItem>
|
||||
)}
|
||||
{update_on_launch && <ListItem>{i18n._(t`Update on Launch`)}</ListItem>}
|
||||
{update_on_project_update && (
|
||||
<ListItem>{i18n._(t`Update on Project Update`)}</ListItem>
|
||||
)}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{summary_fields?.inventory && (
|
||||
<Detail
|
||||
label={i18n._(t`Inventory`)}
|
||||
value={
|
||||
<Link to={`/inventories/${summary_fields.inventory?.id}/details`}>
|
||||
{summary_fields?.inventory?.name}
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Detail label={i18n._(t`Source`)} value={source} />
|
||||
<Detail
|
||||
label={i18n._(t`Ansible Environment`)}
|
||||
value={custom_virtualenv}
|
||||
/>
|
||||
{summary_fields?.source_project && (
|
||||
<Detail
|
||||
label={i18n._(t`Project`)}
|
||||
value={
|
||||
<Link to={`/projects/${summary_fields.source_project?.id}/details`}>
|
||||
{summary_fields.source_project?.name}
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Detail label={i18n._(t`Inventory File`)} value={source_path} />
|
||||
<Detail
|
||||
label={i18n._(t`Custom Inventory Script`)}
|
||||
value={summary_fields?.source_script?.name}
|
||||
/>
|
||||
<Detail label={i18n._(t`Verbosity`)} value={VERBOSITY[verbosity]} />
|
||||
<Detail
|
||||
label={i18n._(t`Cache Timeout`)}
|
||||
value={`${update_cache_timeout} ${i18n._(t`Seconds`)}`}
|
||||
/>
|
||||
{summary_fields?.credentials?.length > 0 && (
|
||||
<Detail
|
||||
fullWidth
|
||||
label={i18n._(t`Credential`)}
|
||||
value={summary_fields.credentials.map(cred => (
|
||||
<CredentialChip key={cred?.id} credential={cred} isReadOnly />
|
||||
))}
|
||||
/>
|
||||
)}
|
||||
{source_regions && (
|
||||
<Detail
|
||||
fullWidth
|
||||
label={i18n._(t`Regions`)}
|
||||
value={
|
||||
<ChipGroup numChips={5}>
|
||||
{source_regions.split(',').map(region => (
|
||||
<Chip key={region} isReadOnly>
|
||||
{region}
|
||||
</Chip>
|
||||
))}
|
||||
</ChipGroup>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{instance_filters && (
|
||||
<Detail
|
||||
fullWidth
|
||||
label={i18n._(t`Instance Filters`)}
|
||||
value={
|
||||
<ChipGroup numChips={5}>
|
||||
{instance_filters.split(',').map(filter => (
|
||||
<Chip key={filter} isReadOnly>
|
||||
{filter}
|
||||
</Chip>
|
||||
))}
|
||||
</ChipGroup>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{group_by && (
|
||||
<Detail
|
||||
fullWidth
|
||||
label={i18n._(t`Only Group By`)}
|
||||
value={
|
||||
<ChipGroup numChips={5}>
|
||||
{group_by.split(',').map(group => (
|
||||
<Chip key={group} isReadOnly>
|
||||
{group}
|
||||
</Chip>
|
||||
))}
|
||||
</ChipGroup>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{optionsList && <Detail label={i18n._(t`Options`)} value={optionsList} />}
|
||||
{source_vars && (
|
||||
<VariablesDetail
|
||||
label={i18n._(t`Source Variables`)}
|
||||
rows={4}
|
||||
value={source_vars}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default withI18n()(PromptInventorySourceDetail);
|
||||
@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
||||
import PromptInventorySourceDetail from './PromptInventorySourceDetail';
|
||||
import mockInvSource from './data.inventory_source.json';
|
||||
|
||||
describe('PromptInventorySourceDetail', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeAll(() => {
|
||||
wrapper = mountWithContexts(
|
||||
<PromptInventorySourceDetail resource={mockInvSource} />
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('should render successfully', () => {
|
||||
expect(wrapper.find('PromptInventorySourceDetail')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('should render expected details', () => {
|
||||
function assertDetail(label, value) {
|
||||
expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label);
|
||||
expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value);
|
||||
}
|
||||
|
||||
assertDetail('Inventory', 'Demo Inventory');
|
||||
assertDetail('Source', 'scm');
|
||||
assertDetail('Project', 'Mock Project');
|
||||
assertDetail('Inventory File', 'foo');
|
||||
assertDetail('Custom Inventory Script', 'Mock Script');
|
||||
assertDetail('Verbosity', '2 (More Verbose)');
|
||||
assertDetail('Cache Timeout', '2 Seconds');
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Regions"]')
|
||||
.containsAllMatchingElements([
|
||||
<span>us-east-1</span>,
|
||||
<span>us-east-2</span>,
|
||||
])
|
||||
).toEqual(true);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Instance Filters"]')
|
||||
.containsAllMatchingElements([
|
||||
<span>filter1</span>,
|
||||
<span>filter2</span>,
|
||||
<span>filter3</span>,
|
||||
])
|
||||
).toEqual(true);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Only Group By"]')
|
||||
.containsAllMatchingElements([
|
||||
<span>group1</span>,
|
||||
<span>group2</span>,
|
||||
<span>group3</span>,
|
||||
])
|
||||
).toEqual(true);
|
||||
expect(wrapper.find('CredentialChip').text()).toBe('Cloud: mock cred');
|
||||
expect(wrapper.find('VariablesDetail').prop('value')).toEqual(
|
||||
'---\nfoo: bar'
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Options"]')
|
||||
.containsAllMatchingElements([
|
||||
<li>Overwrite</li>,
|
||||
<li>Overwrite Variables</li>,
|
||||
<li>Update on Launch</li>,
|
||||
<li>Update on Project Update</li>,
|
||||
])
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import { CardBody } from '@components/Card';
|
||||
|
||||
function PromptJobTemplateDetail() {
|
||||
return <CardBody>Coming soon :)</CardBody>;
|
||||
}
|
||||
|
||||
export default PromptJobTemplateDetail;
|
||||
@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
||||
import PromptProjectDetail from './PromptProjectDetail';
|
||||
import mockProject from './data.project.json';
|
||||
|
||||
describe('PromptProjectDetail', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeAll(() => {
|
||||
const config = {
|
||||
project_base_dir: 'dir/foo/bar',
|
||||
};
|
||||
wrapper = mountWithContexts(
|
||||
<PromptProjectDetail resource={mockProject} />,
|
||||
{
|
||||
context: { config },
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test('should render successfully', () => {
|
||||
expect(wrapper.find('PromptProjectDetail')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('should render expected details', () => {
|
||||
function assertDetail(label, value) {
|
||||
expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label);
|
||||
expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value);
|
||||
}
|
||||
|
||||
assertDetail('SCM Type', 'Git');
|
||||
assertDetail('SCM URL', 'https://github.com/ansible/ansible-tower-samples');
|
||||
assertDetail('SCM Branch', 'foo');
|
||||
assertDetail('SCM Refspec', 'refs/');
|
||||
assertDetail('Cache Timeout', '3 Seconds');
|
||||
assertDetail('Ansible Environment', 'mock virtual env');
|
||||
assertDetail('Project Base Path', 'dir/foo/bar');
|
||||
assertDetail('Playbook Directory', '_6__demo_project');
|
||||
assertDetail('SCM Credential', 'Scm: mock scm');
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Options"]')
|
||||
.containsAllMatchingElements([
|
||||
<li>Clean</li>,
|
||||
<li>Delete on Update</li>,
|
||||
<li>Update Revision on Launch</li>,
|
||||
<li>Allow Branch Override</li>,
|
||||
])
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import { CardBody } from '@components/Card';
|
||||
|
||||
function PromptWFJobTemplateDetail() {
|
||||
return <CardBody>Coming soon :)</CardBody>;
|
||||
}
|
||||
|
||||
export default PromptWFJobTemplateDetail;
|
||||
@ -0,0 +1,118 @@
|
||||
{
|
||||
"id":53,
|
||||
"type":"inventory_source",
|
||||
"url":"/api/v2/inventory_sources/53/",
|
||||
"related":{
|
||||
"named_url":"/api/v2/inventory_sources/src++Demo Inventory++Default/",
|
||||
"created_by":"/api/v2/users/1/",
|
||||
"modified_by":"/api/v2/users/1/",
|
||||
"update":"/api/v2/inventory_sources/53/update/",
|
||||
"inventory_updates":"/api/v2/inventory_sources/53/inventory_updates/",
|
||||
"schedules":"/api/v2/inventory_sources/53/schedules/",
|
||||
"activity_stream":"/api/v2/inventory_sources/53/activity_stream/",
|
||||
"hosts":"/api/v2/inventory_sources/53/hosts/",
|
||||
"groups":"/api/v2/inventory_sources/53/groups/",
|
||||
"notification_templates_started":"/api/v2/inventory_sources/53/notification_templates_started/",
|
||||
"notification_templates_success":"/api/v2/inventory_sources/53/notification_templates_success/",
|
||||
"notification_templates_error":"/api/v2/inventory_sources/53/notification_templates_error/",
|
||||
"inventory":"/api/v2/inventories/1/",
|
||||
"source_project":"/api/v2/projects/8/",
|
||||
"credentials":"/api/v2/inventory_sources/53/credentials/"
|
||||
},
|
||||
"summary_fields":{
|
||||
"organization":{
|
||||
"id":1,
|
||||
"name":"Default",
|
||||
"description":""
|
||||
},
|
||||
"inventory":{
|
||||
"id":1,
|
||||
"name":"Demo Inventory",
|
||||
"description":"",
|
||||
"has_active_failures":false,
|
||||
"total_hosts":1,
|
||||
"hosts_with_active_failures":0,
|
||||
"total_groups":2,
|
||||
"has_inventory_sources":true,
|
||||
"total_inventory_sources":5,
|
||||
"inventory_sources_with_failures":0,
|
||||
"organization_id":1,
|
||||
"kind":""
|
||||
},
|
||||
"source_project":{
|
||||
"id":8,
|
||||
"name":"Mock Project",
|
||||
"description":"",
|
||||
"status":"never updated",
|
||||
"scm_type":"git"
|
||||
},
|
||||
"source_script": {
|
||||
"name": "Mock Script",
|
||||
"description": ""
|
||||
},
|
||||
"created_by":{
|
||||
"id":1,
|
||||
"username":"admin",
|
||||
"first_name":"",
|
||||
"last_name":""
|
||||
},
|
||||
"modified_by":{
|
||||
"id":1,
|
||||
"username":"admin",
|
||||
"first_name":"",
|
||||
"last_name":""
|
||||
},
|
||||
"user_capabilities":{
|
||||
"edit":true,
|
||||
"delete":true,
|
||||
"start":true,
|
||||
"schedule":true
|
||||
},
|
||||
"credential": {
|
||||
"id": 8,
|
||||
"name": "mock cred",
|
||||
"description": "",
|
||||
"kind": "vmware",
|
||||
"cloud": true,
|
||||
"credential_type_id": 7
|
||||
},
|
||||
"credentials":[
|
||||
{
|
||||
"id": 8,
|
||||
"name": "mock cred",
|
||||
"description": "",
|
||||
"kind": "vmware",
|
||||
"cloud": true,
|
||||
"credential_type_id": 7
|
||||
}
|
||||
]
|
||||
},
|
||||
"created":"2020-04-02T18:59:08.474167Z",
|
||||
"modified":"2020-04-02T19:52:23.924252Z",
|
||||
"name":"mock inv source",
|
||||
"description":"mock description",
|
||||
"source":"scm",
|
||||
"source_path": "foo",
|
||||
"source_script": "Mock Script",
|
||||
"source_vars":"---\nfoo: bar",
|
||||
"credential": 8,
|
||||
"source_regions": "us-east-1,us-east-2",
|
||||
"instance_filters": "filter1,filter2,filter3",
|
||||
"group_by": "group1,group2,group3",
|
||||
"overwrite":true,
|
||||
"overwrite_vars":true,
|
||||
"custom_virtualenv":null,
|
||||
"timeout":0,
|
||||
"verbosity":2,
|
||||
"last_job_run":null,
|
||||
"last_job_failed":false,
|
||||
"next_job_run":null,
|
||||
"status":"never updated",
|
||||
"inventory":1,
|
||||
"update_on_launch":true,
|
||||
"update_cache_timeout":2,
|
||||
"source_project":8,
|
||||
"update_on_project_update":true,
|
||||
"last_update_failed": true,
|
||||
"last_updated":null
|
||||
}
|
||||
107
awx/ui_next/src/components/PromptDetail/data.project.json
Normal file
107
awx/ui_next/src/components/PromptDetail/data.project.json
Normal file
@ -0,0 +1,107 @@
|
||||
{
|
||||
"id":6,
|
||||
"type":"project",
|
||||
"url":"/api/v2/projects/6/",
|
||||
"related":{
|
||||
"named_url":"/api/v2/projects/Demo Project++Default/",
|
||||
"created_by":"/api/v2/users/1/",
|
||||
"modified_by":"/api/v2/users/1/",
|
||||
"teams":"/api/v2/projects/6/teams/",
|
||||
"playbooks":"/api/v2/projects/6/playbooks/",
|
||||
"inventory_files":"/api/v2/projects/6/inventories/",
|
||||
"update":"/api/v2/projects/6/update/",
|
||||
"project_updates":"/api/v2/projects/6/project_updates/",
|
||||
"scm_inventory_sources":"/api/v2/projects/6/scm_inventory_sources/",
|
||||
"schedules":"/api/v2/projects/6/schedules/",
|
||||
"activity_stream":"/api/v2/projects/6/activity_stream/",
|
||||
"notification_templates_started":"/api/v2/projects/6/notification_templates_started/",
|
||||
"notification_templates_success":"/api/v2/projects/6/notification_templates_success/",
|
||||
"notification_templates_error":"/api/v2/projects/6/notification_templates_error/",
|
||||
"access_list":"/api/v2/projects/6/access_list/",
|
||||
"object_roles":"/api/v2/projects/6/object_roles/",
|
||||
"copy":"/api/v2/projects/6/copy/",
|
||||
"organization":"/api/v2/organizations/1/"
|
||||
},
|
||||
"summary_fields":{
|
||||
"organization":{
|
||||
"id":1,
|
||||
"name":"Default",
|
||||
"description":""
|
||||
},
|
||||
"credential": {
|
||||
"id": 9,
|
||||
"name": "mock scm",
|
||||
"description": "",
|
||||
"kind": "scm",
|
||||
"cloud": false,
|
||||
"kubernetes": false,
|
||||
"credential_type_id": 2
|
||||
},
|
||||
"created_by":{
|
||||
"id":1,
|
||||
"username":"admin",
|
||||
"first_name":"",
|
||||
"last_name":""
|
||||
},
|
||||
"modified_by":{
|
||||
"id":1,
|
||||
"username":"admin",
|
||||
"first_name":"",
|
||||
"last_name":""
|
||||
},
|
||||
"object_roles":{
|
||||
"admin_role":{
|
||||
"description":"Can manage all aspects of the project",
|
||||
"name":"Admin",
|
||||
"id":15
|
||||
},
|
||||
"use_role":{
|
||||
"description":"Can use the project in a job template",
|
||||
"name":"Use",
|
||||
"id":16
|
||||
},
|
||||
"update_role":{
|
||||
"description":"May update the project",
|
||||
"name":"Update",
|
||||
"id":17
|
||||
},
|
||||
"read_role":{
|
||||
"description":"May view settings for the project",
|
||||
"name":"Read",
|
||||
"id":18
|
||||
}
|
||||
},
|
||||
"user_capabilities":{
|
||||
"edit":true,
|
||||
"delete":true,
|
||||
"start":true,
|
||||
"schedule":true,
|
||||
"copy":true
|
||||
}
|
||||
},
|
||||
"created":"2020-04-02T18:16:15.862724Z",
|
||||
"modified":"2020-04-02T18:16:15.862738Z",
|
||||
"name":"Demo Project",
|
||||
"description":"",
|
||||
"local_path":"_6__demo_project",
|
||||
"scm_type":"git",
|
||||
"scm_url":"https://github.com/ansible/ansible-tower-samples",
|
||||
"scm_branch":"foo",
|
||||
"scm_refspec":"refs/",
|
||||
"scm_clean":true,
|
||||
"scm_delete_on_update":true,
|
||||
"credential":9,
|
||||
"timeout":0,
|
||||
"scm_revision":"",
|
||||
"last_job_run":"2020-03-11T20:18:14Z",
|
||||
"last_job_failed":false,
|
||||
"next_job_run":null,
|
||||
"status":"never updated",
|
||||
"organization":1,
|
||||
"scm_update_on_launch":true,
|
||||
"scm_update_cache_timeout":3,
|
||||
"allow_override":true,
|
||||
"custom_virtualenv": "mock virtual env",
|
||||
"last_update_failed":false,
|
||||
"last_updated":"2020-03-11T20:18:14Z"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user