4d9fa38a5e
* ui: add parameterized dispatch interface This commit adds a new interface for dispatching parameteried jobs, if the user has the right permissions. The UI can be accessed by viewing a parameterized job and clicking on the "Dispatch Job" button located in the "Job Launches" section. * fix failing lint test * clean up dispatch and remove meta This commit cleans up a few things that had typos and inconsistent naming. In line with this, the custom `meta` view was removed in favor of using the included `AttributesTable`. * ui: encode dispatch job payload and start adding tests * ui: remove unused test imports * ui: redesign job dispatch form * ui: initial acceptance tests for dispatch job * ui: generate parameterized job children with correct id format * ui: fix job dispatch breadcrumb link * ui: refactor job dispatch component into glimmer component and add form validation * ui: remove unused CSS class * ui: align job dispatch button * ui: handle namespace-specific requests on job dispatch * ui: rename payloadMissing to payloadHasError * ui: don't re-fetch job spec on dispatch job * ui: keep overview tab selected on job dispatch page * ui: fix task and task-group linting * ui: URL encode job id on dispatch job tests * ui: fix error when job meta is null * ui: handle job dispatch from adapter * ui: add more tests for dispatch job page * ui: add "job dispatch" capability check * ui: update job dispatch from code review Co-authored-by: Luiz Aoqui <luiz@hashicorp.com>
99 lines
2.5 KiB
JavaScript
99 lines
2.5 KiB
JavaScript
import WatchableNamespaceIDs from './watchable-namespace-ids';
|
|
import addToPath from 'nomad-ui/utils/add-to-path';
|
|
import { base64EncodeString } from 'nomad-ui/utils/encode';
|
|
|
|
export default class JobAdapter extends WatchableNamespaceIDs {
|
|
relationshipFallbackLinks = {
|
|
summary: '/summary',
|
|
};
|
|
|
|
fetchRawDefinition(job) {
|
|
const url = this.urlForFindRecord(job.get('id'), 'job');
|
|
return this.ajax(url, 'GET');
|
|
}
|
|
|
|
forcePeriodic(job) {
|
|
if (job.get('periodic')) {
|
|
const url = addToPath(this.urlForFindRecord(job.get('id'), 'job'), '/periodic/force');
|
|
return this.ajax(url, 'POST');
|
|
}
|
|
}
|
|
|
|
stop(job) {
|
|
const url = this.urlForFindRecord(job.get('id'), 'job');
|
|
return this.ajax(url, 'DELETE');
|
|
}
|
|
|
|
parse(spec) {
|
|
const url = addToPath(this.urlForFindAll('job'), '/parse');
|
|
return this.ajax(url, 'POST', {
|
|
data: {
|
|
JobHCL: spec,
|
|
Canonicalize: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
plan(job) {
|
|
const jobId = job.get('id') || job.get('_idBeforeSaving');
|
|
const store = this.store;
|
|
const url = addToPath(this.urlForFindRecord(jobId, 'job'), '/plan');
|
|
|
|
return this.ajax(url, 'POST', {
|
|
data: {
|
|
Job: job.get('_newDefinitionJSON'),
|
|
Diff: true,
|
|
},
|
|
}).then(json => {
|
|
json.ID = jobId;
|
|
store.pushPayload('job-plan', { jobPlans: [json] });
|
|
return store.peekRecord('job-plan', jobId);
|
|
});
|
|
}
|
|
|
|
// Running a job doesn't follow REST create semantics so it's easier to
|
|
// treat it as an action.
|
|
run(job) {
|
|
return this.ajax(this.urlForCreateRecord('job'), 'POST', {
|
|
data: {
|
|
Job: job.get('_newDefinitionJSON'),
|
|
},
|
|
});
|
|
}
|
|
|
|
update(job) {
|
|
const jobId = job.get('id') || job.get('_idBeforeSaving');
|
|
return this.ajax(this.urlForUpdateRecord(jobId, 'job'), 'POST', {
|
|
data: {
|
|
Job: job.get('_newDefinitionJSON'),
|
|
},
|
|
});
|
|
}
|
|
|
|
scale(job, group, count, message) {
|
|
const url = addToPath(this.urlForFindRecord(job.get('id'), 'job'), '/scale');
|
|
return this.ajax(url, 'POST', {
|
|
data: {
|
|
Count: count,
|
|
Message: message,
|
|
Target: {
|
|
Group: group,
|
|
},
|
|
Meta: {
|
|
Source: 'nomad-ui',
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
dispatch(job, meta, payload) {
|
|
const url = addToPath(this.urlForFindRecord(job.get('id'), 'job'), '/dispatch');
|
|
return this.ajax(url, 'POST', {
|
|
data: {
|
|
Payload: base64EncodeString(payload),
|
|
Meta: meta,
|
|
},
|
|
});
|
|
}
|
|
}
|