Scheme: string
}
};
+ Mail?: {
+ SupportEmailAddress: string;
+ };
Services: {
Controller: {
ExternalURL: string
}
WebDAV: {
ExternalURL: string
+ },
+ WebDAVDownload: {
+ ExternalURL: string
+ },
+ WebShell: {
+ ExternalURL: string
}
};
Workbench: {
ArvadosDocsite: string;
VocabularyURL: string;
FileViewersConfigURL: string;
+ WelcomePageHTML: string;
+ InactivePageHTML: string;
+ SSHHelpPageHTML: string;
+ SSHHelpHostSuffix: string;
+ SiteName: string;
+ IdleTimeout: string;
+ };
+ Login: {
+ LoginCluster: string;
+ Google: {
+ Enable: boolean;
+ }
+ LDAP: {
+ Enable: boolean;
+ }
+ OpenIDConnect: {
+ Enable: boolean;
+ }
+ PAM: {
+ Enable: boolean;
+ }
+ SSO: {
+ Enable: boolean;
+ }
+ Test: {
+ Enable: boolean;
+ }
+ };
+ Collections: {
+ ForwardSlashNameSubstitution: string;
};
}
workbench2Url: string;
vocabularyUrl: string;
fileViewersConfigUrl: string;
+ loginCluster: string;
+ clusterConfig: ClusterConfigJSON;
+ apiRevision: number;
}
+export const buildConfig = (clusterConfigJSON: ClusterConfigJSON): Config => {
+ const config = new Config();
+ config.rootUrl = clusterConfigJSON.Services.Controller.ExternalURL;
+ config.baseUrl = `${config.rootUrl}/${ARVADOS_API_PATH}`;
+ config.uuidPrefix = clusterConfigJSON.ClusterID;
+ config.websocketUrl = clusterConfigJSON.Services.Websocket.ExternalURL;
+ config.workbench2Url = clusterConfigJSON.Services.Workbench2.ExternalURL;
+ config.workbenchUrl = clusterConfigJSON.Services.Workbench1.ExternalURL;
+ config.keepWebServiceUrl = clusterConfigJSON.Services.WebDAVDownload.ExternalURL;
+ config.loginCluster = clusterConfigJSON.Login.LoginCluster;
+ config.clusterConfig = clusterConfigJSON;
+ config.apiRevision = 0;
+ mapRemoteHosts(clusterConfigJSON, config);
+ return config;
+};
+
+const getApiRevision = async (apiUrl: string) => {
+ try {
+ const dd = (await Axios.get<any>(`${apiUrl}/${DISCOVERY_DOC_PATH}`)).data;
+ return parseInt(dd.revision, 10) || 0;
+ } catch {
+ console.warn("Unable to get API Revision number, defaulting to zero. Some features may not work properly.");
+ return 0;
+ }
+};
+
+const removeTrailingSlashes = (config: ClusterConfigJSON): ClusterConfigJSON => {
+ const svcs: any = {};
+ Object.keys(config.Services).map((s) => {
+ svcs[s] = config.Services[s];
+ if (svcs[s].hasOwnProperty('ExternalURL')) {
+ svcs[s].ExternalURL = svcs[s].ExternalURL.replace(/\/+$/, '');
+ }
+ });
+ return {...config, Services: svcs};
+};
+
export const fetchConfig = () => {
return Axios
.get<WorkbenchConfig>(WORKBENCH_CONFIG_URL + "?nocache=" + (new Date()).getTime())
if (workbenchConfig.API_HOST === undefined) {
throw new Error(`Unable to start Workbench. API_HOST is undefined in ${WORKBENCH_CONFIG_URL} or the environment.`);
}
- return Axios.get<ClusterConfigJSON>(getClusterConfigURL(workbenchConfig.API_HOST)).then(response => {
- const config = new Config();
- const clusterConfigJSON = response.data;
+ return Axios.get<ClusterConfigJSON>(getClusterConfigURL(workbenchConfig.API_HOST)).then(async response => {
+ const clusterConfigJSON = removeTrailingSlashes(response.data);
+ const apiRevision = await getApiRevision(clusterConfigJSON.Services.Controller.ExternalURL);
+ const config = { ...buildConfig(clusterConfigJSON), apiRevision };
const warnLocalConfig = (varName: string) => console.warn(
`A value for ${varName} was found in ${WORKBENCH_CONFIG_URL}. To use the Arvados centralized configuration instead, \
remove the entire ${varName} entry from ${WORKBENCH_CONFIG_URL}`);
else {
vocabularyUrl = clusterConfigJSON.Workbench.VocabularyURL || "/vocabulary-example.json";
}
- // FIXME: The following line is for dev testing purposes
- vocabularyUrl = "/vocabulary-example.json";
-
config.vocabularyUrl = vocabularyUrl;
- config.rootUrl = clusterConfigJSON.Services.Controller.ExternalURL;
- config.baseUrl = `${config.rootUrl}/${ARVADOS_API_PATH}`;
- config.uuidPrefix = clusterConfigJSON.ClusterID;
- config.websocketUrl = clusterConfigJSON.Services.Websocket.ExternalURL;
- config.workbench2Url = clusterConfigJSON.Services.Workbench2.ExternalURL;
- config.workbenchUrl = clusterConfigJSON.Services.Workbench1.ExternalURL;
- config.keepWebServiceUrl = clusterConfigJSON.Services.WebDAV.ExternalURL;
- mapRemoteHosts(clusterConfigJSON, config);
-
return { config, apiHost: workbenchConfig.API_HOST };
});
});
delete config.remoteHosts["*"];
};
+export const mockClusterConfigJSON = (config: Partial<ClusterConfigJSON>): ClusterConfigJSON => ({
+ ClusterID: "",
+ RemoteClusters: {},
+ Services: {
+ Controller: { ExternalURL: "" },
+ Workbench1: { ExternalURL: "" },
+ Workbench2: { ExternalURL: "" },
+ Websocket: { ExternalURL: "" },
+ WebDAV: { ExternalURL: "" },
+ WebDAVDownload: { ExternalURL: "" },
+ WebShell: { ExternalURL: "" },
+ },
+ Workbench: {
+ ArvadosDocsite: "",
+ VocabularyURL: "",
+ FileViewersConfigURL: "",
+ WelcomePageHTML: "",
+ InactivePageHTML: "",
+ SSHHelpPageHTML: "",
+ SSHHelpHostSuffix: "",
+ SiteName: "",
+ IdleTimeout: "0s",
+ },
+ Login: {
+ LoginCluster: "",
+ Google: {
+ Enable: false,
+ },
+ LDAP: {
+ Enable: false,
+ },
+ OpenIDConnect: {
+ Enable: false,
+ },
+ PAM: {
+ Enable: false,
+ },
+ SSO: {
+ Enable: false,
+ },
+ Test: {
+ Enable: false,
+ },
+ },
+ Collections: {
+ ForwardSlashNameSubstitution: "",
+ },
+ ...config
+});
+
export const mockConfig = (config: Partial<Config>): Config => ({
baseUrl: "",
keepWebServiceUrl: "",
workbenchUrl: "",
workbench2Url: "",
vocabularyUrl: "",
- fileViewersConfigUrl: ""
+ fileViewersConfigUrl: "",
+ loginCluster: "",
+ clusterConfig: mockClusterConfigJSON({}),
+ apiRevision: 0,
+ ...config
});
const getDefaultConfig = (): WorkbenchConfig => {
};
export const ARVADOS_API_PATH = "arvados/v1";
-export const CLUSTER_CONFIG_URL = "arvados/v1/config";
-export const getClusterConfigURL = (apiHost: string) => `${window.location.protocol}//${apiHost}/${CLUSTER_CONFIG_URL}?nocache=${(new Date()).getTime()}`;
\ No newline at end of file
+export const CLUSTER_CONFIG_PATH = "arvados/v1/config";
+export const DISCOVERY_DOC_PATH = "discovery/v1/apis/arvados/v1/rest";
+export const getClusterConfigURL = (apiHost: string) => `${window.location.protocol}//${apiHost}/${CLUSTER_CONFIG_PATH}?nocache=${(new Date()).getTime()}`;