mirror of
https://github.com/ansible/awx.git
synced 2026-04-14 14:39:26 -02:30
Leverage the IG mixin on the schedules model
Move associate/disassociate label methods into mixin Move label/IG saving out to related endpoints off of a schedule
This commit is contained in:
@@ -30,6 +30,20 @@ const LabelsMixin = (parent) =>
|
|||||||
|
|
||||||
return fetchLabels();
|
return fetchLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
associateLabel(id, label, orgId) {
|
||||||
|
return this.http.post(`${this.baseUrl}${id}/labels/`, {
|
||||||
|
name: label.name,
|
||||||
|
organization: orgId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
disassociateLabel(id, label) {
|
||||||
|
return this.http.post(`${this.baseUrl}${id}/labels/`, {
|
||||||
|
id: label.id,
|
||||||
|
disassociate: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LabelsMixin;
|
export default LabelsMixin;
|
||||||
|
|||||||
@@ -34,20 +34,6 @@ class JobTemplates extends SchedulesMixin(
|
|||||||
return this.http.get(`${this.baseUrl}${id}/launch/`);
|
return this.http.get(`${this.baseUrl}${id}/launch/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
associateLabel(id, label, orgId) {
|
|
||||||
return this.http.post(`${this.baseUrl}${id}/labels/`, {
|
|
||||||
name: label.name,
|
|
||||||
organization: orgId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
disassociateLabel(id, label) {
|
|
||||||
return this.http.post(`${this.baseUrl}${id}/labels/`, {
|
|
||||||
id: label.id,
|
|
||||||
disassociate: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
readCredentials(id, params) {
|
readCredentials(id, params) {
|
||||||
return this.http.get(`${this.baseUrl}${id}/credentials/`, {
|
return this.http.get(`${this.baseUrl}${id}/credentials/`, {
|
||||||
params,
|
params,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import Base from '../Base';
|
import Base from '../Base';
|
||||||
|
import InstanceGroupsMixin from '../mixins/InstanceGroups.mixin';
|
||||||
import LabelsMixin from '../mixins/Labels.mixin';
|
import LabelsMixin from '../mixins/Labels.mixin';
|
||||||
|
|
||||||
class Schedules extends LabelsMixin(Base) {
|
class Schedules extends InstanceGroupsMixin(LabelsMixin(Base)) {
|
||||||
constructor(http) {
|
constructor(http) {
|
||||||
super(http);
|
super(http);
|
||||||
this.baseUrl = 'api/v2/schedules/';
|
this.baseUrl = 'api/v2/schedules/';
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act, isElementOfType } from 'react-dom/test-utils';
|
import { act, isElementOfType } from 'react-dom/test-utils';
|
||||||
import {
|
import {
|
||||||
|
ExecutionEnvironmentsAPI,
|
||||||
|
InstanceGroupsAPI,
|
||||||
InventoriesAPI,
|
InventoriesAPI,
|
||||||
CredentialsAPI,
|
CredentialsAPI,
|
||||||
CredentialTypesAPI,
|
CredentialTypesAPI,
|
||||||
@@ -16,15 +18,15 @@ import CredentialsStep from './steps/CredentialsStep';
|
|||||||
import CredentialPasswordsStep from './steps/CredentialPasswordsStep';
|
import CredentialPasswordsStep from './steps/CredentialPasswordsStep';
|
||||||
import OtherPromptsStep from './steps/OtherPromptsStep';
|
import OtherPromptsStep from './steps/OtherPromptsStep';
|
||||||
import PreviewStep from './steps/PreviewStep';
|
import PreviewStep from './steps/PreviewStep';
|
||||||
import executionEnvironmentHelpTextStrings from 'screens/ExecutionEnvironment/shared/ExecutionEnvironment.helptext';
|
|
||||||
import { ExecutionEnvironment } from 'types';
|
|
||||||
import ExecutionEnvironmentStep from './steps/ExecutionEnvironmentStep';
|
import ExecutionEnvironmentStep from './steps/ExecutionEnvironmentStep';
|
||||||
|
import InstanceGroupsStep from './steps/InstanceGroupsStep';
|
||||||
|
|
||||||
jest.mock('../../api/models/Inventories');
|
jest.mock('../../api/models/Inventories');
|
||||||
jest.mock('../../api/models/ExecutionEnvironments');
|
jest.mock('../../api/models/ExecutionEnvironments');
|
||||||
jest.mock('../../api/models/CredentialTypes');
|
jest.mock('../../api/models/CredentialTypes');
|
||||||
jest.mock('../../api/models/Credentials');
|
jest.mock('../../api/models/Credentials');
|
||||||
jest.mock('../../api/models/JobTemplates');
|
jest.mock('../../api/models/JobTemplates');
|
||||||
|
jest.mock('../../api/models/InstanceGroups');
|
||||||
|
|
||||||
let config;
|
let config;
|
||||||
const resource = {
|
const resource = {
|
||||||
@@ -66,6 +68,79 @@ describe('LaunchPrompt', () => {
|
|||||||
spec: [{ type: 'text', variable: 'foo' }],
|
spec: [{ type: 'text', variable: 'foo' }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
InstanceGroupsAPI.read.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
results: [
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
type: 'instance_group',
|
||||||
|
url: '/api/v2/instance_groups/2/',
|
||||||
|
related: {
|
||||||
|
jobs: '/api/v2/instance_groups/2/jobs/',
|
||||||
|
instances: '/api/v2/instance_groups/2/instances/',
|
||||||
|
},
|
||||||
|
name: 'default',
|
||||||
|
created: '2022-08-30T20:35:05.747132Z',
|
||||||
|
modified: '2022-08-30T20:35:05.756690Z',
|
||||||
|
capacity: 177,
|
||||||
|
consumed_capacity: 0,
|
||||||
|
percent_capacity_remaining: 100.0,
|
||||||
|
jobs_running: 0,
|
||||||
|
jobs_total: 2,
|
||||||
|
instances: 3,
|
||||||
|
is_container_group: false,
|
||||||
|
credential: null,
|
||||||
|
policy_instance_percentage: 100,
|
||||||
|
policy_instance_minimum: 0,
|
||||||
|
policy_instance_list: [],
|
||||||
|
pod_spec_override: '',
|
||||||
|
summary_fields: {
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
delete: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
ExecutionEnvironmentsAPI.read.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
results: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
type: 'execution_environment',
|
||||||
|
url: '/api/v2/execution_environments/1/',
|
||||||
|
related: {
|
||||||
|
activity_stream:
|
||||||
|
'/api/v2/execution_environments/1/activity_stream/',
|
||||||
|
unified_job_templates:
|
||||||
|
'/api/v2/execution_environments/1/unified_job_templates/',
|
||||||
|
copy: '/api/v2/execution_environments/1/copy/',
|
||||||
|
},
|
||||||
|
summary_fields: {
|
||||||
|
execution_environment: {},
|
||||||
|
user_capabilities: {
|
||||||
|
edit: true,
|
||||||
|
delete: true,
|
||||||
|
copy: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created: '2022-08-30T20:34:55.842997Z',
|
||||||
|
modified: '2022-08-30T20:34:55.859874Z',
|
||||||
|
name: 'AWX EE (latest)',
|
||||||
|
description: '',
|
||||||
|
organization: null,
|
||||||
|
image: 'quay.io/ansible/awx-ee:latest',
|
||||||
|
managed: false,
|
||||||
|
credential: null,
|
||||||
|
pull: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
can_start_without_user_input: false,
|
can_start_without_user_input: false,
|
||||||
@@ -80,6 +155,12 @@ describe('LaunchPrompt', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: false,
|
ask_inventory_on_launch: false,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -100,6 +181,8 @@ describe('LaunchPrompt', () => {
|
|||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: true,
|
ask_credential_on_launch: true,
|
||||||
ask_scm_branch_on_launch: true,
|
ask_scm_branch_on_launch: true,
|
||||||
|
ask_execution_environment_on_launch: true,
|
||||||
|
ask_instance_groups_on_launch: true,
|
||||||
survey_enabled: true,
|
survey_enabled: true,
|
||||||
passwords_needed_to_start: ['ssh_password'],
|
passwords_needed_to_start: ['ssh_password'],
|
||||||
defaults: {
|
defaults: {
|
||||||
@@ -154,14 +237,15 @@ describe('LaunchPrompt', () => {
|
|||||||
const wizard = await waitForElement(wrapper, 'Wizard');
|
const wizard = await waitForElement(wrapper, 'Wizard');
|
||||||
const steps = wizard.prop('steps');
|
const steps = wizard.prop('steps');
|
||||||
|
|
||||||
expect(steps).toHaveLength(7);
|
expect(steps).toHaveLength(8);
|
||||||
expect(steps[0].name.props.children).toEqual('Inventory');
|
expect(steps[0].name.props.children).toEqual('Inventory');
|
||||||
expect(steps[1].name.props.children).toEqual('Credentials');
|
expect(steps[1].name.props.children).toEqual('Credentials');
|
||||||
expect(steps[2].name.props.children).toEqual('Credential passwords');
|
expect(steps[2].name.props.children).toEqual('Credential passwords');
|
||||||
expect(steps[3].name.props.children).toEqual('Execution Environment');
|
expect(steps[3].name.props.children).toEqual('Execution Environment');
|
||||||
expect(steps[4].name.props.children).toEqual('Other prompts');
|
expect(steps[4].name.props.children).toEqual('Instance Groups');
|
||||||
expect(steps[5].name.props.children).toEqual('Survey');
|
expect(steps[5].name.props.children).toEqual('Other prompts');
|
||||||
expect(steps[6].name.props.children).toEqual('Preview');
|
expect(steps[6].name.props.children).toEqual('Survey');
|
||||||
|
expect(steps[7].name.props.children).toEqual('Preview');
|
||||||
expect(wizard.find('WizardHeader').prop('title')).toBe('Launch | Foobar');
|
expect(wizard.find('WizardHeader').prop('title')).toBe('Launch | Foobar');
|
||||||
expect(wizard.find('WizardHeader').prop('description')).toBe(
|
expect(wizard.find('WizardHeader').prop('description')).toBe(
|
||||||
'Foo Description'
|
'Foo Description'
|
||||||
@@ -219,6 +303,58 @@ describe('LaunchPrompt', () => {
|
|||||||
expect(isElementOfType(steps[2].component, PreviewStep)).toEqual(true);
|
expect(isElementOfType(steps[2].component, PreviewStep)).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should add execution environment step', async () => {
|
||||||
|
let wrapper;
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<LaunchPrompt
|
||||||
|
launchConfig={{
|
||||||
|
...config,
|
||||||
|
ask_execution_environment_on_launch: true,
|
||||||
|
}}
|
||||||
|
resource={resource}
|
||||||
|
onLaunch={noop}
|
||||||
|
onCancel={noop}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const wizard = await waitForElement(wrapper, 'Wizard');
|
||||||
|
const steps = wizard.prop('steps');
|
||||||
|
|
||||||
|
expect(steps).toHaveLength(2);
|
||||||
|
expect(steps[0].name.props.children).toEqual('Execution Environment');
|
||||||
|
expect(
|
||||||
|
isElementOfType(steps[0].component, ExecutionEnvironmentStep)
|
||||||
|
).toEqual(true);
|
||||||
|
expect(isElementOfType(steps[1].component, PreviewStep)).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should add instance groups step', async () => {
|
||||||
|
let wrapper;
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<LaunchPrompt
|
||||||
|
launchConfig={{
|
||||||
|
...config,
|
||||||
|
ask_instance_groups_on_launch: true,
|
||||||
|
}}
|
||||||
|
resource={resource}
|
||||||
|
onLaunch={noop}
|
||||||
|
onCancel={noop}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const wizard = await waitForElement(wrapper, 'Wizard');
|
||||||
|
const steps = wizard.prop('steps');
|
||||||
|
|
||||||
|
expect(steps).toHaveLength(2);
|
||||||
|
expect(steps[0].name.props.children).toEqual('Instance Groups');
|
||||||
|
expect(isElementOfType(steps[0].component, InstanceGroupsStep)).toEqual(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(isElementOfType(steps[1].component, PreviewStep)).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
test('should add other prompts step', async () => {
|
test('should add other prompts step', async () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ function LabelsField() {
|
|||||||
value={field.value}
|
value={field.value}
|
||||||
onChange={(labels) => helpers.setValue(labels)}
|
onChange={(labels) => helpers.setValue(labels)}
|
||||||
createText={t`Create`}
|
createText={t`Create`}
|
||||||
onError={() => alert('error')}
|
onError={() => {}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const STEP_ID = 'credentials';
|
|||||||
export default function useCredentialsStep(
|
export default function useCredentialsStep(
|
||||||
launchConfig,
|
launchConfig,
|
||||||
resource,
|
resource,
|
||||||
resourceDefaultCredentials,
|
resourceDefaultCredentials = [],
|
||||||
allowCredentialsWithPasswords = false
|
allowCredentialsWithPasswords = false
|
||||||
) {
|
) {
|
||||||
const [field, meta, helpers] = useField('credentials');
|
const [field, meta, helpers] = useField('credentials');
|
||||||
@@ -78,6 +78,6 @@ function getInitialValues(launchConfig, resourceDefaultCredentials) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
credentials: resourceDefaultCredentials || [],
|
credentials: resourceDefaultCredentials,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useHistory, useLocation } from 'react-router-dom';
|
|||||||
import { Card } from '@patternfly/react-core';
|
import { Card } from '@patternfly/react-core';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { parseVariableField } from 'util/yaml';
|
import { parseVariableField } from 'util/yaml';
|
||||||
import { LabelsAPI, OrganizationsAPI, SchedulesAPI } from 'api';
|
import { OrganizationsAPI, SchedulesAPI } from 'api';
|
||||||
import mergeExtraVars from 'util/prompt/mergeExtraVars';
|
import mergeExtraVars from 'util/prompt/mergeExtraVars';
|
||||||
import getSurveyValues from 'util/prompt/getSurveyValues';
|
import getSurveyValues from 'util/prompt/getSurveyValues';
|
||||||
import { getAddedAndRemoved } from 'util/lists';
|
import { getAddedAndRemoved } from 'util/lists';
|
||||||
@@ -41,6 +41,7 @@ function ScheduleAdd({
|
|||||||
exceptionOptions,
|
exceptionOptions,
|
||||||
timezone,
|
timezone,
|
||||||
credentials,
|
credentials,
|
||||||
|
labels,
|
||||||
...submitValues
|
...submitValues
|
||||||
} = values;
|
} = values;
|
||||||
const { added } = getAddedAndRemoved(
|
const { added } = getAddedAndRemoved(
|
||||||
@@ -76,56 +77,7 @@ function ScheduleAdd({
|
|||||||
submitValues.execution_environment = execution_environment.id;
|
submitValues.execution_environment = execution_environment.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
submitValues.instance_groups = instance_groups
|
|
||||||
? instance_groups.map((s) => s.id)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (launchConfiguration?.ask_labels_on_launch) {
|
|
||||||
const labelIds = [];
|
|
||||||
const newLabels = [];
|
|
||||||
const labelRequests = [];
|
|
||||||
let organizationId = resource.organization;
|
|
||||||
if (values.labels) {
|
|
||||||
values.labels.forEach((label) => {
|
|
||||||
if (typeof label.id !== 'number') {
|
|
||||||
newLabels.push(label);
|
|
||||||
} else {
|
|
||||||
labelIds.push(label.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newLabels.length > 0) {
|
|
||||||
if (!organizationId) {
|
|
||||||
// eslint-disable-next-line no-useless-catch
|
|
||||||
try {
|
|
||||||
const {
|
|
||||||
data: { results },
|
|
||||||
} = await OrganizationsAPI.read();
|
|
||||||
organizationId = results[0].id;
|
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newLabels.forEach((label) => {
|
|
||||||
labelRequests.push(
|
|
||||||
LabelsAPI.create({
|
|
||||||
name: label.name,
|
|
||||||
organization: organizationId,
|
|
||||||
}).then(({ data }) => {
|
|
||||||
labelIds.push(data.id);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
await Promise.all(labelRequests);
|
|
||||||
|
|
||||||
submitValues.labels = labelIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ruleSet = buildRuleSet(values);
|
const ruleSet = buildRuleSet(values);
|
||||||
const requestData = {
|
const requestData = {
|
||||||
...submitValues,
|
...submitValues,
|
||||||
@@ -147,13 +99,46 @@ function ScheduleAdd({
|
|||||||
const {
|
const {
|
||||||
data: { id: scheduleId },
|
data: { id: scheduleId },
|
||||||
} = await apiModel.createSchedule(resource.id, requestData);
|
} = await apiModel.createSchedule(resource.id, requestData);
|
||||||
if (credentials?.length > 0) {
|
|
||||||
await Promise.all(
|
let labelsPromises = [];
|
||||||
added.map(({ id: credentialId }) =>
|
let credentialsPromises = [];
|
||||||
SchedulesAPI.associateCredential(scheduleId, credentialId)
|
|
||||||
)
|
if (launchConfiguration?.ask_labels_on_launch && labels) {
|
||||||
|
let organizationId = resource.organization;
|
||||||
|
if (!organizationId) {
|
||||||
|
// eslint-disable-next-line no-useless-catch
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
data: { results },
|
||||||
|
} = await OrganizationsAPI.read();
|
||||||
|
organizationId = results[0].id;
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labelsPromises = labels.map((label) =>
|
||||||
|
SchedulesAPI.associateLabel(scheduleId, label, organizationId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (launchConfiguration?.ask_credential_on_launch && added?.length > 0) {
|
||||||
|
credentialsPromises = added.map(({ id: credentialId }) =>
|
||||||
|
SchedulesAPI.associateCredential(scheduleId, credentialId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await Promise.all([labelsPromises, credentialsPromises]);
|
||||||
|
|
||||||
|
if (
|
||||||
|
launchConfiguration?.ask_instance_groups_on_launch &&
|
||||||
|
instance_groups
|
||||||
|
) {
|
||||||
|
/* eslint-disable no-await-in-loop, no-restricted-syntax */
|
||||||
|
for (const group of instance_groups) {
|
||||||
|
await SchedulesAPI.associateInstanceGroup(scheduleId, group.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
history.push(`${pathRoot}schedules/${scheduleId}`);
|
history.push(`${pathRoot}schedules/${scheduleId}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setFormSubmitError(err);
|
setFormSubmitError(err);
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { RRule } from 'rrule';
|
import { RRule } from 'rrule';
|
||||||
import { SchedulesAPI, JobTemplatesAPI, InventoriesAPI } from 'api';
|
import {
|
||||||
|
CredentialsAPI,
|
||||||
|
CredentialTypesAPI,
|
||||||
|
SchedulesAPI,
|
||||||
|
JobTemplatesAPI,
|
||||||
|
InventoriesAPI,
|
||||||
|
} from 'api';
|
||||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||||
import ScheduleAdd from './ScheduleAdd';
|
import ScheduleAdd from './ScheduleAdd';
|
||||||
|
|
||||||
jest.mock('../../../api');
|
jest.mock('../../../api/models/Credentials');
|
||||||
|
jest.mock('../../../api/models/CredentialTypes');
|
||||||
|
jest.mock('../../../api/models/Schedules');
|
||||||
|
jest.mock('../../../api/models/JobTemplates');
|
||||||
|
jest.mock('../../../api/models/Inventories');
|
||||||
|
|
||||||
const launchConfig = {
|
const launchConfig = {
|
||||||
can_start_without_user_input: false,
|
can_start_without_user_input: false,
|
||||||
@@ -19,7 +29,7 @@ const launchConfig = {
|
|||||||
ask_limit_on_launch: false,
|
ask_limit_on_launch: false,
|
||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: true,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -57,6 +67,33 @@ describe('<ScheduleAdd />', () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
JobTemplatesAPI.createSchedule.mockResolvedValue({ data: { id: 3 } });
|
JobTemplatesAPI.createSchedule.mockResolvedValue({ data: { id: 3 } });
|
||||||
|
|
||||||
|
CredentialTypesAPI.loadAllTypes.mockResolvedValue([
|
||||||
|
{ id: 1, name: 'ssh', kind: 'ssh' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
CredentialsAPI.read.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
count: 1,
|
||||||
|
results: [
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
name: 'cred 1',
|
||||||
|
kind: 'ssh',
|
||||||
|
url: '',
|
||||||
|
credential_type: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
CredentialsAPI.readOptions.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
related_search_fields: [],
|
||||||
|
actions: { GET: { filterabled: true } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<ScheduleAdd
|
<ScheduleAdd
|
||||||
@@ -70,6 +107,7 @@ describe('<ScheduleAdd />', () => {
|
|||||||
description: '',
|
description: '',
|
||||||
}}
|
}}
|
||||||
launchConfig={launchConfig}
|
launchConfig={launchConfig}
|
||||||
|
surveyConfig={{}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -390,6 +428,7 @@ describe('<ScheduleAdd />', () => {
|
|||||||
wrapper.find('Button[aria-label="Prompt"]').prop('onClick')()
|
wrapper.find('Button[aria-label="Prompt"]').prop('onClick')()
|
||||||
);
|
);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
// Inventory step
|
||||||
expect(wrapper.find('WizardNavItem').at(0).prop('isCurrent')).toBe(true);
|
expect(wrapper.find('WizardNavItem').at(0).prop('isCurrent')).toBe(true);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper.find('td#check-action-item-1').find('input').simulate('click');
|
wrapper.find('td#check-action-item-1').find('input').simulate('click');
|
||||||
@@ -402,7 +441,21 @@ describe('<ScheduleAdd />', () => {
|
|||||||
wrapper.find('WizardFooterInternal').prop('onNext')()
|
wrapper.find('WizardFooterInternal').prop('onNext')()
|
||||||
);
|
);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
// Credential step
|
||||||
expect(wrapper.find('WizardNavItem').at(1).prop('isCurrent')).toBe(true);
|
expect(wrapper.find('WizardNavItem').at(1).prop('isCurrent')).toBe(true);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('td#check-action-item-10').find('input').simulate('click');
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(
|
||||||
|
wrapper.find('td#check-action-item-10').find('input').prop('checked')
|
||||||
|
).toBe(true);
|
||||||
|
await act(async () =>
|
||||||
|
wrapper.find('WizardFooterInternal').prop('onNext')()
|
||||||
|
);
|
||||||
|
wrapper.update();
|
||||||
|
// Preview step
|
||||||
|
expect(wrapper.find('WizardNavItem').at(2).prop('isCurrent')).toBe(true);
|
||||||
await act(async () =>
|
await act(async () =>
|
||||||
wrapper.find('WizardFooterInternal').prop('onNext')()
|
wrapper.find('WizardFooterInternal').prop('onNext')()
|
||||||
);
|
);
|
||||||
@@ -414,10 +467,7 @@ describe('<ScheduleAdd />', () => {
|
|||||||
frequency: [],
|
frequency: [],
|
||||||
skip_tags: '',
|
skip_tags: '',
|
||||||
inventory: { name: 'inventory', id: 45 },
|
inventory: { name: 'inventory', id: 45 },
|
||||||
credentials: [
|
credentials: [{ name: 'cred 1', id: 10 }],
|
||||||
{ name: 'cred 1', id: 10 },
|
|
||||||
{ name: 'cred 2', id: 20 },
|
|
||||||
],
|
|
||||||
startDate: '2021-01-28',
|
startDate: '2021-01-28',
|
||||||
startTime: '2:15 PM',
|
startTime: '2:15 PM',
|
||||||
timezone: 'America/New_York',
|
timezone: 'America/New_York',
|
||||||
@@ -434,7 +484,6 @@ describe('<ScheduleAdd />', () => {
|
|||||||
skip_tags: '',
|
skip_tags: '',
|
||||||
});
|
});
|
||||||
expect(SchedulesAPI.associateCredential).toBeCalledWith(3, 10);
|
expect(SchedulesAPI.associateCredential).toBeCalledWith(3, 10);
|
||||||
expect(SchedulesAPI.associateCredential).toBeCalledWith(3, 20);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should submit survey with default values properly, without opening prompt wizard', async () => {
|
test('should submit survey with default values properly, without opening prompt wizard', async () => {
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ function ScheduleEdit({
|
|||||||
values,
|
values,
|
||||||
launchConfiguration,
|
launchConfiguration,
|
||||||
surveyConfiguration,
|
surveyConfiguration,
|
||||||
scheduleCredentials = []
|
scheduleCredentials = [],
|
||||||
|
originalLabels = []
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
execution_environment,
|
execution_environment,
|
||||||
@@ -42,13 +43,9 @@ function ScheduleEdit({
|
|||||||
exceptionFrequency,
|
exceptionFrequency,
|
||||||
exceptionOptions,
|
exceptionOptions,
|
||||||
timezone,
|
timezone,
|
||||||
|
labels,
|
||||||
...submitValues
|
...submitValues
|
||||||
} = values;
|
} = values;
|
||||||
const { added, removed } = getAddedAndRemoved(
|
|
||||||
[...(resource?.summary_fields.credentials || []), ...scheduleCredentials],
|
|
||||||
credentials
|
|
||||||
);
|
|
||||||
|
|
||||||
let extraVars;
|
let extraVars;
|
||||||
const surveyValues = getSurveyValues(values);
|
const surveyValues = getSurveyValues(values);
|
||||||
|
|
||||||
@@ -86,10 +83,6 @@ function ScheduleEdit({
|
|||||||
submitValues.execution_environment = execution_environment.id;
|
submitValues.execution_environment = execution_environment.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
submitValues.instance_groups = instance_groups
|
|
||||||
? instance_groups.map((s) => s.id)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (launchConfiguration?.ask_labels_on_launch) {
|
if (launchConfiguration?.ask_labels_on_launch) {
|
||||||
const labelIds = [];
|
const labelIds = [];
|
||||||
@@ -157,17 +150,52 @@ function ScheduleEdit({
|
|||||||
const {
|
const {
|
||||||
data: { id: scheduleId },
|
data: { id: scheduleId },
|
||||||
} = await SchedulesAPI.update(schedule.id, requestData);
|
} = await SchedulesAPI.update(schedule.id, requestData);
|
||||||
if (values.credentials?.length > 0) {
|
|
||||||
await Promise.all([
|
const { added: addedCredentials, removed: removedCredentials } =
|
||||||
...removed.map(({ id }) =>
|
getAddedAndRemoved(
|
||||||
SchedulesAPI.disassociateCredential(scheduleId, id)
|
[
|
||||||
),
|
...(resource?.summary_fields.credentials || []),
|
||||||
...added.map(({ id }) =>
|
...scheduleCredentials,
|
||||||
SchedulesAPI.associateCredential(scheduleId, id)
|
],
|
||||||
),
|
credentials
|
||||||
]);
|
);
|
||||||
|
|
||||||
|
const { added: addedLabels, removed: removedLabels } = getAddedAndRemoved(
|
||||||
|
originalLabels,
|
||||||
|
labels
|
||||||
|
);
|
||||||
|
|
||||||
|
let organizationId = resource.organization;
|
||||||
|
|
||||||
|
if (addedLabels.length > 0) {
|
||||||
|
if (!organizationId) {
|
||||||
|
const {
|
||||||
|
data: { results },
|
||||||
|
} = await OrganizationsAPI.read();
|
||||||
|
organizationId = results[0].id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
...removedCredentials.map(({ id }) =>
|
||||||
|
SchedulesAPI.disassociateCredential(scheduleId, id)
|
||||||
|
),
|
||||||
|
...addedCredentials.map(({ id }) =>
|
||||||
|
SchedulesAPI.associateCredential(scheduleId, id)
|
||||||
|
),
|
||||||
|
...removedLabels.map((label) =>
|
||||||
|
SchedulesAPI.disassociateLabel(scheduleId, label)
|
||||||
|
),
|
||||||
|
...addedLabels.map((label) =>
|
||||||
|
SchedulesAPI.associateLabel(scheduleId, label, organizationId)
|
||||||
|
),
|
||||||
|
SchedulesAPI.orderInstanceGroups(
|
||||||
|
scheduleId,
|
||||||
|
instance_groups,
|
||||||
|
resource?.summary_fields.instance_groups || []
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
history.push(`${pathRoot}schedules/${scheduleId}/details`);
|
history.push(`${pathRoot}schedules/${scheduleId}/details`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setFormSubmitError(err);
|
setFormSubmitError(err);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function ScheduleForm({
|
|||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
const { data } = await SchedulesAPI.readZoneInfo();
|
const { data } = await SchedulesAPI.readZoneInfo();
|
||||||
|
|
||||||
let creds;
|
let creds = [];
|
||||||
let allLabels;
|
let allLabels;
|
||||||
if (schedule.id) {
|
if (schedule.id) {
|
||||||
if (
|
if (
|
||||||
@@ -107,7 +107,7 @@ function ScheduleForm({
|
|||||||
return {
|
return {
|
||||||
zoneOptions: zones,
|
zoneOptions: zones,
|
||||||
zoneLinks: data.links,
|
zoneLinks: data.links,
|
||||||
credentials: creds || [],
|
credentials: creds,
|
||||||
labels: allLabels || [],
|
labels: allLabels || [],
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
@@ -467,7 +467,13 @@ function ScheduleForm({
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onSubmit={(values) => {
|
onSubmit={(values) => {
|
||||||
submitSchedule(values, launchConfig, surveyConfig, credentials);
|
submitSchedule(
|
||||||
|
values,
|
||||||
|
launchConfig,
|
||||||
|
surveyConfig,
|
||||||
|
credentials,
|
||||||
|
labels
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
validate={validate}
|
validate={validate}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -17,11 +17,35 @@ jest.mock('../../../api/models/Inventories');
|
|||||||
const credentials = {
|
const credentials = {
|
||||||
data: {
|
data: {
|
||||||
results: [
|
results: [
|
||||||
{ id: 1, kind: 'cloud', name: 'Cred 1', url: 'www.google.com' },
|
{
|
||||||
{ id: 2, kind: 'ssh', name: 'Cred 2', url: 'www.google.com' },
|
id: 1,
|
||||||
{ id: 3, kind: 'Ansible', name: 'Cred 3', url: 'www.google.com' },
|
kind: 'cloud',
|
||||||
{ id: 4, kind: 'Machine', name: 'Cred 4', url: 'www.google.com' },
|
name: 'Cred 1',
|
||||||
{ id: 5, kind: 'Machine', name: 'Cred 5', url: 'www.google.com' },
|
url: 'www.google.com',
|
||||||
|
inputs: {},
|
||||||
|
},
|
||||||
|
{ id: 2, kind: 'ssh', name: 'Cred 2', url: 'www.google.com', inputs: {} },
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
kind: 'Ansible',
|
||||||
|
name: 'Cred 3',
|
||||||
|
url: 'www.google.com',
|
||||||
|
inputs: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
kind: 'Machine',
|
||||||
|
name: 'Cred 4',
|
||||||
|
url: 'www.google.com',
|
||||||
|
inputs: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
kind: 'Machine',
|
||||||
|
name: 'Cred 5',
|
||||||
|
url: 'www.google.com',
|
||||||
|
inputs: {},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -39,6 +63,12 @@ const launchData = {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -153,6 +183,12 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -208,6 +244,12 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -275,6 +317,12 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -406,6 +454,12 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: true,
|
ask_inventory_on_launch: true,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -465,6 +519,12 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: false,
|
ask_inventory_on_launch: false,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -894,7 +954,7 @@ describe('<ScheduleForm />', () => {
|
|||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should make API calls to fetch credentials, launch configuration, and survey configuration', async () => {
|
test('should make API calls to fetch credentials, labels, and zone info', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<ScheduleForm
|
<ScheduleForm
|
||||||
@@ -906,6 +966,9 @@ describe('<ScheduleForm />', () => {
|
|||||||
type: 'job_template',
|
type: 'job_template',
|
||||||
name: 'Foo Job Template',
|
name: 'Foo Job Template',
|
||||||
description: '',
|
description: '',
|
||||||
|
summary_fields: {
|
||||||
|
credentials: [],
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
launchConfig={{
|
launchConfig={{
|
||||||
can_start_without_user_input: true,
|
can_start_without_user_input: true,
|
||||||
@@ -919,7 +982,13 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_limit_on_launch: false,
|
ask_limit_on_launch: false,
|
||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: false,
|
ask_inventory_on_launch: false,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: true,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: true,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -933,7 +1002,9 @@ describe('<ScheduleForm />', () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
expect(SchedulesAPI.readZoneInfo).toBeCalled();
|
||||||
expect(SchedulesAPI.readCredentials).toBeCalledWith(27);
|
expect(SchedulesAPI.readCredentials).toBeCalledWith(27);
|
||||||
|
expect(SchedulesAPI.readAllLabels).toBeCalledWith(27);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not call API to get credentials ', async () => {
|
test('should not call API to get credentials ', async () => {
|
||||||
@@ -961,6 +1032,12 @@ describe('<ScheduleForm />', () => {
|
|||||||
ask_verbosity_on_launch: false,
|
ask_verbosity_on_launch: false,
|
||||||
ask_inventory_on_launch: false,
|
ask_inventory_on_launch: false,
|
||||||
ask_credential_on_launch: false,
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
survey_enabled: false,
|
survey_enabled: false,
|
||||||
variables_needed_to_start: [],
|
variables_needed_to_start: [],
|
||||||
credential_needed_to_start: false,
|
credential_needed_to_start: false,
|
||||||
@@ -991,6 +1068,30 @@ describe('<ScheduleForm />', () => {
|
|||||||
name: 'Foo Project',
|
name: 'Foo Project',
|
||||||
description: '',
|
description: '',
|
||||||
}}
|
}}
|
||||||
|
launchConfig={{
|
||||||
|
can_start_without_user_input: true,
|
||||||
|
passwords_needed_to_start: [],
|
||||||
|
ask_scm_branch_on_launch: false,
|
||||||
|
ask_variables_on_launch: false,
|
||||||
|
ask_tags_on_launch: false,
|
||||||
|
ask_diff_mode_on_launch: false,
|
||||||
|
ask_skip_tags_on_launch: false,
|
||||||
|
ask_job_type_on_launch: false,
|
||||||
|
ask_limit_on_launch: false,
|
||||||
|
ask_verbosity_on_launch: false,
|
||||||
|
ask_inventory_on_launch: false,
|
||||||
|
ask_credential_on_launch: false,
|
||||||
|
ask_execution_environment_on_launch: false,
|
||||||
|
ask_labels_on_launch: false,
|
||||||
|
ask_forks_on_launch: false,
|
||||||
|
ask_job_slice_count_on_launch: false,
|
||||||
|
ask_timeout_on_launch: false,
|
||||||
|
ask_instance_groups_on_launch: false,
|
||||||
|
survey_enabled: false,
|
||||||
|
variables_needed_to_start: [],
|
||||||
|
credential_needed_to_start: false,
|
||||||
|
inventory_needed_to_start: false,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user