366 lines
8.7 KiB
JavaScript
366 lines
8.7 KiB
JavaScript
// Copyright 2018 Red Hat, Inc
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
// License for the specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
import Axios from 'axios'
|
|
|
|
let authToken = undefined
|
|
|
|
export function setAuthToken(token) {
|
|
authToken = token
|
|
}
|
|
|
|
function getHomepageUrl() {
|
|
//
|
|
// Discover serving location from href.
|
|
//
|
|
// This is only needed for sub-directory serving. Serving the application
|
|
// from 'scheme://domain/' may simply default to 'scheme://domain/'
|
|
//
|
|
// Note that this is not enough for sub-directory serving,
|
|
// The static files location also needs to be adapted with the 'homepage'
|
|
// settings of the package.json file.
|
|
//
|
|
// This homepage url is used for the Router and Link resolution logic
|
|
//
|
|
let url = new URL(window.location.href)
|
|
|
|
if ('PUBLIC_URL' in process.env) {
|
|
url.pathname = process.env.PUBLIC_URL
|
|
} else {
|
|
url.pathname = ''
|
|
}
|
|
if (!url.pathname.endsWith('/')) {
|
|
url.pathname = url.pathname + '/'
|
|
}
|
|
return url.origin + url.pathname
|
|
}
|
|
|
|
function getZuulUrl() {
|
|
// Return the zuul root api absolute url
|
|
const ZUUL_API = process.env.REACT_APP_ZUUL_API
|
|
let apiUrl
|
|
|
|
if (ZUUL_API) {
|
|
// Api url set at build time, use it
|
|
apiUrl = ZUUL_API
|
|
} else {
|
|
// Api url is relative to homepage path
|
|
apiUrl = getHomepageUrl() + 'api/'
|
|
}
|
|
if (!apiUrl.endsWith('/')) {
|
|
apiUrl = apiUrl + '/'
|
|
}
|
|
if (!apiUrl.endsWith('/api/')) {
|
|
apiUrl = apiUrl + 'api/'
|
|
}
|
|
// console.log('Api url is ', apiUrl)
|
|
return apiUrl
|
|
}
|
|
const apiUrl = getZuulUrl()
|
|
|
|
|
|
function getStreamUrl(apiPrefix) {
|
|
const streamUrl = (apiUrl + apiPrefix)
|
|
.replace(/(http)(s)?:\/\//, 'ws$2://') + 'console-stream'
|
|
// console.log('Stream url is ', streamUrl)
|
|
return streamUrl
|
|
}
|
|
|
|
function getAuthToken() {
|
|
return authToken
|
|
}
|
|
|
|
function makeRequest(url, method, data) {
|
|
if (method === undefined) {
|
|
method = 'get'
|
|
}
|
|
|
|
// This performs a simple GET and tries to detect if CORS errors are
|
|
// due to proxy authentication errors.
|
|
const instance = Axios.create({
|
|
baseURL: apiUrl
|
|
})
|
|
|
|
if (authToken) {
|
|
instance.defaults.headers.common['Authorization'] = 'Bearer ' + authToken
|
|
}
|
|
|
|
const config = {method, url, data}
|
|
|
|
// First try the request as normal
|
|
let res = instance.request(config).catch(err => {
|
|
if (err.response === undefined) {
|
|
// This is either a Network, DNS, or CORS error, but we can't tell which.
|
|
// If we're behind an authz proxy, it's possible our creds have timed out
|
|
// and the CORS error is because we're getting a redirect.
|
|
// Apache mod_auth_mellon (and possibly other authz proxies) will avoid
|
|
// issuing a redirect if X-Requested-With is set to 'XMLHttpRequest' and
|
|
// will instead issue a 403. We can use this to detect that case.
|
|
instance.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
|
|
let res2 = instance.request(config).catch(err2 => {
|
|
if (err2.response && err2.response.status === 403) {
|
|
// We might be getting a redirect or something else,
|
|
// so reload the page.
|
|
console.log('Received 403 after unknown error; reloading')
|
|
window.location.reload()
|
|
}
|
|
// If we're still getting an error, we don't know the cause,
|
|
// it could be a transient network error, so we won't reload, we'll just
|
|
// wait for it to clear.
|
|
throw (err2)
|
|
})
|
|
return res2
|
|
}
|
|
throw (err)
|
|
})
|
|
return res
|
|
}
|
|
|
|
// Direct APIs
|
|
function fetchInfo() {
|
|
return makeRequest('info')
|
|
}
|
|
|
|
function fetchComponents() {
|
|
return makeRequest('components')
|
|
}
|
|
|
|
function fetchTenantInfo(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'info')
|
|
}
|
|
|
|
function fetchOpenApi() {
|
|
return Axios.get(getHomepageUrl() + 'openapi.yaml')
|
|
}
|
|
|
|
function fetchTenants() {
|
|
return makeRequest(apiUrl + 'tenants')
|
|
}
|
|
|
|
function fetchConfigErrors(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'config-errors')
|
|
}
|
|
|
|
function fetchStatus(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'status')
|
|
}
|
|
|
|
function fetchChangeStatus(apiPrefix, changeId) {
|
|
return makeRequest(apiPrefix + 'status/change/' + changeId)
|
|
}
|
|
|
|
function fetchFreezeJob(apiPrefix, pipelineName, projectName, branchName, jobName) {
|
|
return makeRequest(apiPrefix +
|
|
'pipeline/' + pipelineName +
|
|
'/project/' + projectName +
|
|
'/branch/' + branchName +
|
|
'/freeze-job/' + jobName)
|
|
}
|
|
|
|
function fetchBuild(apiPrefix, buildId) {
|
|
return makeRequest(apiPrefix + 'build/' + buildId)
|
|
}
|
|
|
|
function fetchBuilds(apiPrefix, queryString) {
|
|
let path = 'builds'
|
|
if (queryString) {
|
|
path += '?' + queryString.slice(1)
|
|
}
|
|
return makeRequest(apiPrefix + path)
|
|
}
|
|
|
|
function fetchBuildset(apiPrefix, buildsetId) {
|
|
return makeRequest(apiPrefix + 'buildset/' + buildsetId)
|
|
}
|
|
|
|
function fetchBuildsets(apiPrefix, queryString) {
|
|
let path = 'buildsets'
|
|
if (queryString) {
|
|
path += '?' + queryString.slice(1)
|
|
}
|
|
return makeRequest(apiPrefix + path)
|
|
}
|
|
|
|
function fetchPipelines(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'pipelines')
|
|
}
|
|
|
|
function fetchProject(apiPrefix, projectName) {
|
|
return makeRequest(apiPrefix + 'project/' + projectName)
|
|
}
|
|
|
|
function fetchProjects(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'projects')
|
|
}
|
|
|
|
function fetchJob(apiPrefix, jobName) {
|
|
return makeRequest(apiPrefix + 'job/' + jobName)
|
|
}
|
|
|
|
function fetchJobGraph(apiPrefix, projectName, pipelineName, branchName) {
|
|
return makeRequest(apiPrefix +
|
|
'pipeline/' + pipelineName +
|
|
'/project/' + projectName +
|
|
'/branch/' + branchName +
|
|
'/freeze-jobs')
|
|
}
|
|
|
|
function fetchJobs(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'jobs')
|
|
}
|
|
|
|
function fetchLabels(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'labels')
|
|
}
|
|
|
|
function fetchNodes(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'nodes')
|
|
}
|
|
|
|
function fetchSemaphores(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'semaphores')
|
|
}
|
|
|
|
function fetchAutoholds(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'autohold')
|
|
}
|
|
|
|
function fetchAutohold(apiPrefix, requestId) {
|
|
return makeRequest(apiPrefix + 'autohold/' + requestId)
|
|
}
|
|
|
|
function fetchUserAuthorizations(apiPrefix) {
|
|
return makeRequest(apiPrefix + 'authorizations')
|
|
}
|
|
|
|
function dequeue(apiPrefix, projectName, pipeline, change) {
|
|
return makeRequest(
|
|
apiPrefix + 'project/' + projectName + '/dequeue',
|
|
'post',
|
|
{
|
|
pipeline: pipeline,
|
|
change: change,
|
|
}
|
|
)
|
|
}
|
|
|
|
function dequeue_ref(apiPrefix, projectName, pipeline, ref) {
|
|
return makeRequest(
|
|
apiPrefix + 'project/' + projectName + '/dequeue',
|
|
'post',
|
|
{
|
|
pipeline: pipeline,
|
|
ref: ref,
|
|
}
|
|
)
|
|
}
|
|
|
|
function enqueue(apiPrefix, projectName, pipeline, change) {
|
|
return makeRequest(
|
|
apiPrefix + 'project/' + projectName + '/enqueue',
|
|
'post',
|
|
{
|
|
pipeline: pipeline,
|
|
change: change,
|
|
}
|
|
)
|
|
}
|
|
|
|
function enqueue_ref(apiPrefix, projectName, pipeline, ref, oldrev, newrev) {
|
|
return makeRequest(
|
|
apiPrefix + 'project/' + projectName + '/enqueue',
|
|
'post',
|
|
{
|
|
pipeline: pipeline,
|
|
ref: ref,
|
|
oldrev: oldrev,
|
|
newrev: newrev,
|
|
}
|
|
)
|
|
}
|
|
|
|
function autohold(apiPrefix, projectName, job, change, ref,
|
|
reason, count, node_hold_expiration) {
|
|
return makeRequest(
|
|
apiPrefix + 'project/' + projectName + '/autohold',
|
|
'post',
|
|
{
|
|
change: change,
|
|
job: job,
|
|
ref: ref,
|
|
reason: reason,
|
|
count: count,
|
|
node_hold_expiration: node_hold_expiration,
|
|
}
|
|
)
|
|
}
|
|
|
|
function autohold_delete(apiPrefix, requestId) {
|
|
return makeRequest(
|
|
apiPrefix + '/autohold/' + requestId,
|
|
'delete'
|
|
)
|
|
}
|
|
|
|
function promote(apiPrefix, pipeline, changes) {
|
|
return makeRequest(
|
|
apiPrefix + '/promote',
|
|
'post',
|
|
{
|
|
pipeline: pipeline,
|
|
changes: changes,
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
export {
|
|
apiUrl,
|
|
getHomepageUrl,
|
|
getStreamUrl,
|
|
getAuthToken,
|
|
fetchChangeStatus,
|
|
fetchConfigErrors,
|
|
fetchStatus,
|
|
fetchBuild,
|
|
fetchBuilds,
|
|
fetchBuildset,
|
|
fetchBuildsets,
|
|
fetchFreezeJob,
|
|
fetchPipelines,
|
|
fetchProject,
|
|
fetchProjects,
|
|
fetchJob,
|
|
fetchJobGraph,
|
|
fetchJobs,
|
|
fetchLabels,
|
|
fetchNodes,
|
|
fetchOpenApi,
|
|
fetchSemaphores,
|
|
fetchTenants,
|
|
fetchInfo,
|
|
fetchComponents,
|
|
fetchTenantInfo,
|
|
fetchUserAuthorizations,
|
|
fetchAutoholds,
|
|
fetchAutohold,
|
|
autohold,
|
|
autohold_delete,
|
|
dequeue,
|
|
dequeue_ref,
|
|
enqueue,
|
|
enqueue_ref,
|
|
promote,
|
|
}
|