mirror of
https://github.com/ansible/awx.git
synced 2026-03-09 05:29:26 -02: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:
@@ -10,6 +10,9 @@ import { VariablesDetail } from '@components/CodeMirrorInput';
|
|||||||
import { DetailList, Detail, UserDateDetail } from '@components/DetailList';
|
import { DetailList, Detail, UserDateDetail } from '@components/DetailList';
|
||||||
|
|
||||||
import PromptProjectDetail from './PromptProjectDetail';
|
import PromptProjectDetail from './PromptProjectDetail';
|
||||||
|
import PromptInventorySourceDetail from './PromptInventorySourceDetail';
|
||||||
|
import PromptJobTemplateDetail from './PromptJobTemplateDetail';
|
||||||
|
import PromptWFJobTemplateDetail from './PromptWFJobTemplateDetail';
|
||||||
|
|
||||||
const PromptHeader = styled.h2`
|
const PromptHeader = styled.h2`
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -84,6 +87,15 @@ function PromptDetail({ i18n, resource, launchConfig = {} }) {
|
|||||||
{resource?.type === 'project' && (
|
{resource?.type === 'project' && (
|
||||||
<PromptProjectDetail resource={resource} />
|
<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
|
<UserDateDetail
|
||||||
label={i18n._(t`Created`)}
|
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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user