@roadiehq/backstage-plugin-argo-cd-backend
Version:
990 lines (984 loc) • 31.4 kB
JavaScript
;
var fetch = require('cross-fetch');
var timer_services = require('./timer.services.cjs.js');
var getArgoConfig = require('../utils/getArgoConfig.cjs.js');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
const APP_NAMESPACE_QUERY_PARAM = "appNamespace";
class ArgoService {
constructor(username, password, config, logger) {
this.username = username;
this.password = password;
this.config = config;
this.logger = logger;
this.instanceConfigs = this.config.getConfigArray("argocd.appLocatorMethods").filter((element) => element.getString("type") === "config").reduce(
(acc, argoApp) => acc.concat(argoApp.getConfigArray("instances")),
[]
).map((instance) => ({
name: instance.getString("name"),
url: instance.getString("url"),
token: instance.getOptionalString("token"),
username: instance.getOptionalString("username"),
password: instance.getOptionalString("password")
}));
}
instanceConfigs;
getArgoInstanceArray() {
return this.getAppArray().map((instance) => ({
name: instance.getString("name"),
url: instance.getString("url"),
token: instance.getOptionalString("token"),
username: instance.getOptionalString("username"),
password: instance.getOptionalString("password")
}));
}
getAppArray() {
const argoApps = this.config.getConfigArray("argocd.appLocatorMethods").filter((element) => element.getString("type") === "config");
return argoApps.reduce(
(acc, argoApp) => acc.concat(argoApp.getConfigArray("instances")),
[]
);
}
async getRevisionData(baseUrl, options, argoToken, revisionID) {
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
}
};
const urlBuilder = new URL(
`${baseUrl}/api/v1/applications/${options.name}/revisions/${revisionID}/metadata`
);
if (options.namespace) {
urlBuilder.searchParams.set(APP_NAMESPACE_QUERY_PARAM, options.namespace);
}
if (options.sourceIndex) {
urlBuilder.searchParams.set("sourceIndex", options.sourceIndex);
}
const url = urlBuilder.toString();
const resp = await fetch__default.default(url, requestOptions);
if (!resp.ok) {
throw new Error(`Request failed with ${resp.status} Error`);
}
const data = await resp?.json();
return data;
}
async findArgoApp(options) {
if (!options.name && !options.selector) {
throw new Error("name or selector is required");
}
const resp = await Promise.all(
this.instanceConfigs.map(async (argoInstance) => {
let getArgoAppDataResp;
let token;
try {
token = await this.getArgoToken(argoInstance);
} catch (error) {
this.logger.error(
`Error getting token from Argo Instance ${argoInstance.name}: ${error.message}`
);
return null;
}
try {
getArgoAppDataResp = await this.getArgoAppData(
argoInstance.url,
argoInstance.name,
token,
options
);
} catch (error) {
this.logger.error(
`Error getting Argo App Data from Argo Instance ${argoInstance.name}: ${error.message}`
);
return null;
}
if (options.selector && !getArgoAppDataResp.items) {
return null;
}
return {
name: argoInstance.name,
url: argoInstance.url,
appName: options.selector ? getArgoAppDataResp.items.map((x) => x.metadata.name) : [options.name]
};
})
).catch();
return resp.flatMap((f) => f ? [f] : []);
}
async getArgoProject({
baseUrl,
argoToken,
projectName
}) {
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
}
};
const resp = await fetch__default.default(
`${baseUrl}/api/v1/projects/${projectName}`,
requestOptions
);
const data = await resp.json();
if (resp.status !== 200) {
this.logger.error(
`Failed to get argo project ${projectName}: ${data.message}`
);
throw new Error(`Failed to get argo project: ${data.message}`);
}
return data;
}
async getArgoToken(argoInstanceConfig) {
const oidcConfig = this.config.getOptional("argocd.oidcConfig");
const { url, username, password, token } = argoInstanceConfig;
if (token) return token;
if (username && password || this.username && this.password) {
const resp = await fetch__default.default(`${url}/api/v1/session`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
username: username || this.username,
password: password || this.password
})
});
if (!resp.ok) {
this.logger.error(`failed to get argo token: ${url}`);
}
if (resp.status === 401) {
throw new Error(`Getting unauthorized for Argo CD instance ${url}`);
}
const data = await resp.json();
return data.token;
}
if (oidcConfig?.provider === "azure" && oidcConfig.providerConfigKey) {
const azureCredentials = this.config.get(
oidcConfig.providerConfigKey
);
const resp = await fetch__default.default(
`${azureCredentials.loginUrl}/${azureCredentials.tenantId}/oauth2/v2.0/token`,
{
method: "POST",
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: azureCredentials.clientId,
client_secret: azureCredentials.clientSecret,
scope: `${azureCredentials.clientId}/.default`
}).toString()
}
);
const data = await resp.json();
if ("error" in data) {
throw new Error(
`Failed to get argo token through your azure config credentials: ${data.error_description} (${data.error}, codes: [${data.error_codes}], status code: ${resp.status})`
);
}
return data.access_token;
}
throw new Error("Missing credentials in config for Argo Instance.");
}
async getArgoAppData(baseUrl, argoInstanceName, argoToken, options) {
let urlSuffix = "";
if (options?.name) {
urlSuffix = `/${options.name}`;
if (options?.namespace) {
urlSuffix = `${urlSuffix}?${APP_NAMESPACE_QUERY_PARAM}=${options.namespace}`;
}
}
if (options?.selector) {
urlSuffix = `?selector=${options.selector}`;
if (options?.namespace) {
urlSuffix = `${urlSuffix}&${APP_NAMESPACE_QUERY_PARAM}=${options.namespace}`;
}
}
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
}
};
const resp = await fetch__default.default(
`${baseUrl}/api/v1/applications${urlSuffix}`,
requestOptions
);
if (!resp.ok) {
throw new Error(`Request failed with ${resp.status} Error`);
}
const data = await resp?.json();
if (data.items) {
data.items.forEach((item) => {
item.metadata.instance = { name: argoInstanceName };
});
} else if (data && options?.name) {
data.instance = argoInstanceName;
}
return data;
}
buildArgoProjectPayload({
projectName,
namespace,
destinationServer,
resourceVersion,
sourceRepo
}) {
const clusterResourceBlacklist = this.config.getOptional(
`argocd.projectSettings.clusterResourceBlacklist`
);
const clusterResourceWhitelist = this.config.getOptional(
`argocd.projectSettings.clusterResourceWhitelist`
);
const namespaceResourceBlacklist = this.config.getOptional(
`argocd.projectSettings.namespaceResourceBlacklist`
);
const namespaceResourceWhitelist = this.config.getOptional(
`argocd.projectSettings.namespaceResourceWhitelist`
);
const project = {
metadata: {
name: projectName,
resourceVersion,
finalizers: ["resources-finalizer.argocd.argoproj.io"]
},
spec: {
destinations: [
{
name: "local",
namespace,
server: destinationServer ?? "https://kubernetes.default.svc"
}
],
...clusterResourceBlacklist && { clusterResourceBlacklist },
...clusterResourceWhitelist && { clusterResourceWhitelist },
...namespaceResourceBlacklist && { namespaceResourceBlacklist },
...namespaceResourceWhitelist && { namespaceResourceWhitelist },
sourceRepos: Array.isArray(sourceRepo) ? sourceRepo : [sourceRepo]
}
};
return project;
}
async createArgoProject({
baseUrl,
argoToken,
projectName,
namespace,
sourceRepo,
destinationServer
}) {
const data = {
project: this.buildArgoProjectPayload({
projectName,
namespace,
sourceRepo,
destinationServer
})
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
},
body: JSON.stringify(data)
};
const resp = await fetch__default.default(`${baseUrl}/api/v1/projects`, options);
const responseData = await resp.json();
if (resp.status === 403) {
throw new Error(responseData.message);
} else if (resp.status === 404) {
return resp.json();
} else if (JSON.stringify(responseData).includes(
"existing project spec is different"
)) {
throw new Error("Duplicate project detected. Cannot overwrite existing.");
}
return responseData;
}
async updateArgoProject({
baseUrl,
argoToken,
projectName,
namespace,
sourceRepo,
resourceVersion,
destinationServer
}) {
const data = {
project: this.buildArgoProjectPayload({
projectName,
namespace,
sourceRepo,
resourceVersion,
destinationServer
})
};
const options = {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
},
body: JSON.stringify(data)
};
const resp = await fetch__default.default(
`${baseUrl}/api/v1/projects/${projectName}`,
options
);
const responseData = await resp.json();
if (resp.status !== 200) {
this.logger.error(
`Error updating argo project ${projectName}: ${responseData.message}`
);
throw new Error(`Error updating argo project: ${responseData.message}`);
}
return responseData;
}
buildArgoApplicationPayload({
appName,
projectName,
namespace,
sourceRepo,
sourcePath,
labelValue,
resourceVersion,
destinationServer
}) {
return {
metadata: {
name: appName,
labels: { "backstage-name": labelValue },
finalizers: ["resources-finalizer.argocd.argoproj.io"],
resourceVersion
},
spec: {
destination: {
namespace,
server: destinationServer ? destinationServer : "https://kubernetes.default.svc"
},
project: projectName,
revisionHistoryLimit: 10,
source: {
path: sourcePath,
repoURL: sourceRepo
},
syncPolicy: {
automated: {
allowEmpty: true,
prune: true,
selfHeal: true
},
retry: {
backoff: {
duration: "5s",
factor: 2,
maxDuration: "5m"
},
limit: 10
},
syncOptions: ["CreateNamespace=false", "FailOnSharedResource=true"]
}
}
};
}
async createArgoApplication({
baseUrl,
argoToken,
appName,
projectName,
namespace,
sourceRepo,
sourcePath,
labelValue,
destinationServer
}) {
const data = this.buildArgoApplicationPayload({
appName,
projectName,
namespace,
sourcePath,
sourceRepo,
labelValue,
destinationServer
});
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
},
body: JSON.stringify(data)
};
const resp = await fetch__default.default(`${baseUrl}/api/v1/applications`, options);
const respData = await resp.json();
if (!resp.ok) {
throw new Error(`Error creating argo app: ${respData.message}`);
}
return respData;
}
async resyncAppOnAllArgos({
appSelector,
terminateOperation
}) {
const argoAppResp = await this.findArgoApp({
selector: appSelector
});
if (argoAppResp) {
const parallelSyncCalls = argoAppResp.map(
async (argoInstance) => {
try {
const token = await this.getArgoToken(argoInstance);
try {
if (terminateOperation) {
const terminateResp = argoInstance.appName.map(
(argoApp) => {
return this.terminateArgoAppOperation({
baseUrl: argoInstance.url,
argoAppName: argoApp,
argoToken: token
});
}
);
await Promise.all(terminateResp);
}
const resp = argoInstance.appName.map(
(argoApp) => {
return this.syncArgoApp({
argoInstance,
argoToken: token,
appName: argoApp
});
}
);
return await Promise.all(resp);
} catch (e) {
return [{ status: "Failure", message: e.message }];
}
} catch (e) {
return [{ status: "Failure", message: e.message }];
}
}
);
return await Promise.all(parallelSyncCalls);
}
return [];
}
async syncArgoApp({
argoInstance,
argoToken,
appName
}) {
const data = {
prune: false,
dryRun: false,
strategy: {
hook: {
force: true
}
},
resources: null
};
const options = {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${argoToken}`
}
};
const resp = await fetch__default.default(
`${argoInstance.url}/api/v1/applications/${appName}/sync`,
options
);
if (resp.ok) {
return {
status: "Success",
message: `Re-synced ${appName} on ${argoInstance.name}`
};
}
return {
message: `Failed to resync ${appName} on ${argoInstance.name}`,
status: "Failure"
};
}
async updateArgoApp({
baseUrl,
argoToken,
appName,
projectName,
namespace,
sourceRepo,
sourcePath,
labelValue,
resourceVersion,
destinationServer
}) {
const data = this.buildArgoApplicationPayload({
appName,
projectName,
namespace,
sourceRepo,
sourcePath,
labelValue,
resourceVersion,
destinationServer
});
const options = {
method: "PUT",
headers: {
Authorization: `Bearer ${argoToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify(data)
};
const resp = await fetch__default.default(
`${baseUrl}/api/v1/applications/${appName}`,
options
);
const respData = await resp.json();
if (resp.status !== 200) {
this.logger.error(
`Error updating argo app ${appName}: ${respData.message}`
);
throw new Error(`Error updating argo app: ${respData.message}`);
}
return respData;
}
// @see https://cd.apps.argoproj.io/swagger-ui#operation/ApplicationService_Delete
async deleteApp({
baseUrl,
argoApplicationName,
argoToken
}) {
const options = {
method: "DELETE",
headers: {
Authorization: `Bearer ${argoToken}`,
"Content-Type": "application/json"
}
};
let statusText = "";
try {
const response = await fetch__default.default(
`${baseUrl}/api/v1/applications/${argoApplicationName}?${new URLSearchParams(
{
cascade: "true"
}
)}`,
options
);
statusText = response.statusText;
if (response.status === 200) {
return { ...await response.json(), statusCode: response.status };
}
return { ...await response.json(), statusCode: response.status };
} catch (error) {
this.logger.error(
`Error Deleting Argo Application for application ${argoApplicationName} in ${baseUrl} - ${JSON.stringify(
{ statusText, error: error.message }
)}`
);
throw error;
}
}
// @see https://cd.apps.argoproj.io/swagger-ui#operation/ProjectService_Delete
async deleteProject({
baseUrl,
argoProjectName,
argoToken
}) {
const options = {
method: "DELETE",
headers: {
Authorization: `Bearer ${argoToken}`,
"Content-Type": "application/json"
}
};
let statusText = "";
try {
const response = await fetch__default.default(
`${baseUrl}/api/v1/projects/${argoProjectName}`,
options
);
statusText = response.statusText;
if (response.status === 200) {
return { ...await response.json(), statusCode: response.status };
}
return { ...await response.json(), statusCode: response.status };
} catch (error) {
this.logger.error(
`Error Deleting Argo Project for project ${argoProjectName} in ${baseUrl} - ${JSON.stringify(
{ statusText, error: error.message }
)}`
);
throw error;
}
}
async deleteAppandProject({
argoAppName,
argoInstanceName,
terminateOperation
}) {
let continueToDeleteProject = false;
let deleteAppDetails;
let deleteProjectDetails;
let terminateOperationDetails;
const matchedArgoInstance = this.instanceConfigs.find(
(argoInstance) => argoInstance.name === argoInstanceName
);
if (matchedArgoInstance === void 0) {
throw new Error("cannot find an argo instance to match this cluster");
}
const token = await this.getArgoToken(matchedArgoInstance);
if (terminateOperation) {
const terminateOperationResp = await this.terminateArgoAppOperation({
baseUrl: matchedArgoInstance.url,
argoAppName,
argoToken: token
});
if (terminateOperationResp.statusCode !== 404 && terminateOperationResp.statusCode !== 200 && "message" in terminateOperationResp) {
terminateOperationDetails = {
status: "failed",
argoResponse: terminateOperationResp,
message: `failed to terminate ${argoAppName}'s operation for application`
};
} else if (terminateOperationResp.statusCode === 404) {
terminateOperationDetails = {
status: "failed",
argoResponse: terminateOperationResp,
message: `application ${argoAppName} not found`
};
} else if (terminateOperationResp.statusCode === 200) {
terminateOperationDetails = {
status: "success",
argoResponse: terminateOperationResp,
message: `${argoAppName}'s current operation terminated`
};
}
}
const deleteAppResp = await this.deleteApp({
baseUrl: matchedArgoInstance.url,
argoApplicationName: argoAppName,
argoToken: token
});
if (deleteAppResp.statusCode !== 404 && deleteAppResp.statusCode !== 200 && "message" in deleteAppResp) {
deleteAppDetails = {
status: "failed",
message: `failed to delete application ${argoAppName}`,
argoResponse: deleteAppResp
};
} else if (deleteAppResp.statusCode === 404) {
continueToDeleteProject = true;
deleteAppDetails = {
status: "success",
message: `application ${argoAppName} does not exist and therefore does not need to be deleted`,
argoResponse: deleteAppResp
};
} else if (deleteAppResp.statusCode === 200) {
deleteAppDetails = {
status: "pending",
message: `application ${argoAppName} pending deletion`,
argoResponse: deleteAppResp
};
const configuredWaitCycles = this.config.getOptionalNumber("argocd.waitCycles") || 1;
const configuredWaitInterval = this.config.getOptionalNumber("argocd.waitInterval") || 5e3;
for (let attempts = 0; attempts < configuredWaitCycles; attempts++) {
const applicationInfo = await this.getArgoApplicationInfo({
baseUrl: matchedArgoInstance.url,
argoApplicationName: argoAppName,
argoToken: token
});
deleteAppDetails.argoResponse = applicationInfo;
if (applicationInfo.statusCode !== 404 && "message" in applicationInfo) {
deleteAppDetails.status = "failed";
deleteAppDetails.message = `a request was successfully sent to delete application ${argoAppName}, but when getting your application information we received an error`;
break;
} else if (applicationInfo.statusCode === 404) {
continueToDeleteProject = true;
deleteAppDetails.status = "success";
deleteAppDetails.message = `application ${argoAppName} deletion verified (application no longer exists)`;
break;
} else if (applicationInfo.statusCode === 200 && "metadata" in applicationInfo) {
deleteAppDetails.status = "pending";
deleteAppDetails.message = `application ${argoAppName} still pending deletion with the deletion timestamp of ${applicationInfo.metadata.deletionTimestamp}`;
if (attempts < configuredWaitCycles - 1)
await timer_services.timer(configuredWaitInterval);
}
}
}
if (continueToDeleteProject) {
const deleteProjectResponse = await this.deleteProject({
baseUrl: matchedArgoInstance.url,
argoProjectName: argoAppName,
argoToken: token
});
if (deleteProjectResponse.statusCode !== 404 && deleteProjectResponse.statusCode !== 200 && "message" in deleteProjectResponse) {
deleteProjectDetails = {
status: "failed",
message: `failed to delete project ${argoAppName}.`,
argoResponse: deleteProjectResponse
};
} else if (deleteProjectResponse.statusCode === 404) {
deleteProjectDetails = {
status: "success",
message: `project ${argoAppName} does not exist and therefore does not need to be deleted.`,
argoResponse: deleteProjectResponse
};
} else if (deleteProjectResponse.statusCode === 200) {
deleteProjectDetails = {
status: "pending",
message: `project ${argoAppName} is pending deletion.`,
argoResponse: deleteProjectResponse
};
}
} else {
deleteProjectDetails = {
status: "failed",
message: `project ${argoAppName} deletion skipped due to application still existing and pending deletion, or the application failed to delete.`,
argoResponse: {}
};
}
return {
...terminateOperationDetails ? { terminateOperationDetails } : {},
deleteAppDetails,
deleteProjectDetails
};
}
async createArgoResources({
argoInstance,
appName,
projectName,
namespace,
sourceRepo,
sourcePath,
labelValue,
logger
}) {
logger.info(`Getting app ${appName} on ${argoInstance}`);
const matchedArgoInstance = this.instanceConfigs.find(
(argoHost) => argoHost.name === argoInstance
);
if (!matchedArgoInstance) {
throw new Error(`Unable to find Argo instance named '${argoInstance}'`);
}
const token = await this.getArgoToken(matchedArgoInstance);
await this.createArgoProject({
baseUrl: matchedArgoInstance.url,
argoToken: token,
projectName: projectName ? projectName : appName,
namespace,
sourceRepo
});
await this.createArgoApplication({
baseUrl: matchedArgoInstance.url,
argoToken: token,
appName,
projectName: projectName ? projectName : appName,
namespace,
sourceRepo,
sourcePath,
labelValue: labelValue ? labelValue : appName
});
return true;
}
async updateArgoProjectAndApp({
instanceConfig,
argoToken,
appName,
projectName,
namespace,
sourceRepo,
sourcePath,
labelValue,
destinationServer
}) {
const appData = await this.getArgoAppData(
instanceConfig.url,
instanceConfig.name,
argoToken,
{ name: appName }
);
if (!appData.spec?.source?.repoURL) {
this.logger.error(`No repo URL found for argo app ${projectName}`);
throw new Error("No repo URL found for argo app");
}
if (!appData.metadata?.resourceVersion) {
this.logger.error(`No resourceVersion found for argo app ${projectName}`);
throw new Error("No resourceVersion found for argo app");
}
const projData = await this.getArgoProject({
baseUrl: instanceConfig.url,
argoToken,
projectName
});
if (!projData.metadata?.resourceVersion) {
this.logger.error(
`No resourceVersion found for argo project ${projectName}`
);
throw new Error("No resourceVersion found for argo project");
}
if (appData.spec?.source?.repoURL === sourceRepo) {
await this.updateArgoProject({
argoToken,
baseUrl: instanceConfig.url,
namespace,
projectName,
sourceRepo,
resourceVersion: projData.metadata.resourceVersion,
destinationServer
});
await this.updateArgoApp({
appName,
argoToken,
baseUrl: instanceConfig.url,
labelValue,
namespace,
projectName,
sourcePath,
sourceRepo,
resourceVersion: appData.metadata.resourceVersion,
destinationServer
});
return true;
}
await this.updateArgoProject({
argoToken,
baseUrl: instanceConfig.url,
namespace,
projectName,
sourceRepo: [sourceRepo, appData.spec.source.repoURL],
resourceVersion: projData.metadata.resourceVersion,
destinationServer
});
await this.updateArgoApp({
appName,
argoToken,
baseUrl: instanceConfig.url,
labelValue,
namespace,
projectName,
sourcePath,
sourceRepo,
resourceVersion: appData.metadata.resourceVersion,
destinationServer
});
const updatedProjData = await this.getArgoProject({
baseUrl: instanceConfig.url,
argoToken,
projectName
});
await this.updateArgoProject({
argoToken,
baseUrl: instanceConfig.url,
namespace,
projectName,
sourceRepo,
resourceVersion: updatedProjData.metadata.resourceVersion,
destinationServer
});
return true;
}
// @see https://cd.apps.argoproj.io/swagger-ui#operation/ApplicationService_List
async getArgoApplicationInfo(props) {
const argoApplicationName = props.argoApplicationName;
let url = "baseUrl" in props ? props.baseUrl : void 0;
let token = "argoToken" in props ? props.argoToken : void 0;
const argoInstanceName = "argoInstanceName" in props ? props.argoInstanceName : void 0;
if (!(url && token)) {
if (!argoInstanceName)
throw new Error(
`argo instance must be defined when baseurl or token are not given.`
);
const matchedArgoInstance = getArgoConfig.getArgoConfigByInstanceName({
argoConfigs: this.instanceConfigs,
argoInstanceName
});
if (!matchedArgoInstance)
throw new Error(
`config does not have argo information for the cluster named '${argoInstanceName}'`
);
token = await this.getArgoToken(matchedArgoInstance);
url = matchedArgoInstance.url;
}
const options = {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
method: "GET"
};
let statusText = "";
try {
const response = await fetch__default.default(
`${url}/api/v1/applications/${argoApplicationName}`,
options
);
statusText = response.statusText;
if (response.status === 200) {
return { ...await response.json(), statusCode: response.status };
}
return { ...await response.json(), statusCode: response.status };
} catch (error) {
this.logger.error(
`Error Getting Argo Application Information For Argo Instance Name ${argoInstanceName ?? url} - searching for application ${argoApplicationName} - ${JSON.stringify(
{ statusText, error: error.message }
)}`
);
throw error;
}
}
// @see https://cd.apps.argoproj.io/swagger-ui#operation/ApplicationService_TerminateOperation
async terminateArgoAppOperation(props) {
const argoApplicationName = props.argoAppName;
let url = "baseUrl" in props ? props.baseUrl : void 0;
let token = "argoToken" in props ? props.argoToken : void 0;
const argoInstanceName = "argoInstanceName" in props ? props.argoInstanceName : void 0;
if (!(url && token)) {
if (!argoInstanceName)
throw new Error(
`argo instance must be defined when baseurl or token are not given.`
);
const matchedArgoInstance = getArgoConfig.getArgoConfigByInstanceName({
argoConfigs: this.instanceConfigs,
argoInstanceName
});
if (!matchedArgoInstance)
throw new Error(
`config does not have argo information for the cluster named '${argoInstanceName}'`
);
token = await this.getArgoToken(matchedArgoInstance);
url = matchedArgoInstance.url;
}
const options = {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
method: "DELETE"
};
this.logger.info(
`Terminating current operation for ${argoInstanceName ?? url} and ${argoApplicationName}`
);
let statusText = "";
try {
const response = await fetch__default.default(
`${url}/api/v1/applications/${argoApplicationName}/operation`,
options
);
statusText = response.statusText;
if (response.status === 200) {
return { ...await response.json(), statusCode: response.status };
}
return { ...await response.json(), statusCode: response.status };
} catch (error) {
this.logger.error(
`Error Terminating Argo Application Operation for application ${argoApplicationName} in Argo Instance Name ${argoInstanceName ?? url} - ${JSON.stringify({ statusText, error: error.message })}`
);
throw error;
}
}
}
exports.ArgoService = ArgoService;
//# sourceMappingURL=argocd.service.cjs.js.map