Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set 5 second timeout for cluster server connection that requires VPN and minor code clean-up #141

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
29 changes: 11 additions & 18 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export async function activate(context: vscode.ExtensionContext) {
// Register Commands
vscode.commands.executeCommand("setContext", VSCodeCommands.sdkInstalled, await session.validateOcSDKInstallation());
vscode.commands.executeCommand("setContext", VSCodeCommands.loggedIn, await session.validateOpenShiftAccess());
vscode.commands.executeCommand("setContext", VSCodeCommands.validNamespace, await session.validateNamespaceExist());
vscode.commands.executeCommand("setContext", VSCodeCommands.validNamespace, await session.validateNamespaceExists());
vscode.commands.executeCommand("setContext", VSCodeCommands.sdkOutdatedVersion, await session.determinateOcSdkIsOutdated());
vscode.commands.executeCommand("setContext", VSCodeCommands.zosCloudBrokerInstalled, await session.validateZosCloudBrokerInstallation());
vscode.commands.executeCommand("setContext", VSCodeCommands.isCollectionInWorkspace, await util.isCollectionInWorkspace(session.skipOCinit));
Expand Down Expand Up @@ -552,7 +552,7 @@ function updateOcSdkVersion(command: string, ocSdkCmd: OcSdkCommand, session: Se
function initOperatorCollection(command: string, session: Session, outputChannel?: vscode.OutputChannel): vscode.Disposable {
return vscode.commands.registerCommand(command, async (uri, _, logPath?: string) => {
if (session.operationPending) {
vscode.window.showWarningMessage("Another operation is processing.");
vscode.window.showWarningMessage("Please wait for the current operation to finish before initializing a new collection.");
return;
}

Expand Down Expand Up @@ -920,36 +920,34 @@ function executeSimpleSdkCommand(command: string, session: Session, outputChanne
}
vscode.window.showInformationMessage("Redeploy Collection request in progress");
const poll = util.pollRun(30);
const runRedeployCollectionCommand = ocSdkCommand.runRedeployCollectionCommand(outputChannel, logPath).then(() => {
session.operationPending = false;
});
const runRedeployCollectionCommand = ocSdkCommand.runRedeployCollectionCommand(outputChannel, logPath);
Promise.all([poll, runRedeployCollectionCommand])
.then(() => {
session.operationPending = false;
vscode.window.showInformationMessage("Redeploy Collection command executed successfully");
vscode.commands.executeCommand(VSCodeCommands.refresh);
})
.catch(e => {
session.operationPending = false;
showErrorMessage(`Failure executing Redeploy Collection command: ${e}`);
})
.finally(() => {
session.operationPending = false;
});
break;
}
case VSCodeCommands.redeployOperator: {
vscode.window.showInformationMessage("Redeploy Operator request in progress");
const poll = util.pollRun(40);
const runRedeployOperatorCommand = ocSdkCommand.runRedeployOperatorCommand(outputChannel, logPath).then(() => {
session.operationPending = false;
});
const runRedeployOperatorCommand = ocSdkCommand.runRedeployOperatorCommand(outputChannel, logPath);
Promise.all([poll, runRedeployOperatorCommand])
.then(() => {
session.operationPending = false;
vscode.window.showInformationMessage("Redeploy Operator command executed successfully");
vscode.commands.executeCommand(VSCodeCommands.refresh);
})
.catch(e => {
session.operationPending = false;
showErrorMessage(`Failure executing Redeploy Operator command: ${e}`);
})
.finally(() => {
session.operationPending = false;
});
break;
}
Expand Down Expand Up @@ -1001,12 +999,7 @@ function executeSdkCommandWithUserInput(command: string, session: Session, outpu
vscode.window.showInformationMessage("Create Operator request in progress");
}
session.operationPending = true;
Promise.all([
util.pollRun(40),
ocSdkCommand.runCreateOperatorCommand(playbookArgs, outputChannel, logPath).then(() => {
session.operationPending = false;
}),
])
Promise.all([util.pollRun(40), ocSdkCommand.runCreateOperatorCommand(playbookArgs, outputChannel, logPath)])
.then(() => {
session.operationPending = false;
vscode.window.showInformationMessage("Create Operator command executed successfully");
Expand Down
27 changes: 26 additions & 1 deletion src/kubernetes/kubernetes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ export class KubernetesObj extends KubernetesContext {
* @returns - A promise containing a list of namespaces if the namespace exist in the list
*/
public async validateNamespaceExists(): Promise<boolean | undefined> {
return this.coreV1Api
const namespaceExists = this.coreV1Api
?.readNamespace(this.namespace)
?.then(() => {
return true;
Expand All @@ -616,6 +616,31 @@ export class KubernetesObj extends KubernetesContext {
console.log("Failure retrieving Namespace " + this.namespace);
return false;
});

// Cancel request after 5 seconds without a response from the readNamespace request.
// This usually implies a connectivity issue with OpenShift, which could take a minute or more
// before receiving the timeout response.
let timeout: NodeJS.Timeout | undefined = undefined;
const timeoutPromise: Promise<boolean> = new Promise(resolve => {
timeout = setTimeout(() => {
vscode.window.showWarningMessage("Connection timed out... Please validate the connectivity to OpenShift");
resolve(false);
}, 5000);
});

const done = Promise.race([namespaceExists, timeoutPromise])
.then(value => {
return value;
})
.catch(() => {
return false;
})
.finally(() => {
if (timeout) {
clearTimeout(timeout);
}
});
return done;
}

public async signatureValidationRequiredForOperator(operatorName: string, version: string): Promise<boolean | undefined> {
Expand Down
29 changes: 16 additions & 13 deletions src/utilities/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as vscode from "vscode";
import { OcSdkCommand } from "../shellCommands/ocSdkCommands";
import { KubernetesObj } from "../kubernetes/kubernetes";
import { VSCodeCommands } from "../utilities/commandConstants";
import { getAnsibleGalaxySettings, AnsibleGalaxySettings, isCollectionInWorkspace } from "../utilities/util";
import { getAnsibleGalaxySettings, AnsibleGalaxySettings } from "../utilities/util";

export class Session {
public ocSdkInstalled: boolean = false;
Expand All @@ -23,11 +23,11 @@ export class Session {

async update(skipRefresh?: boolean, skipOcSdkValidation?: boolean): Promise<boolean> {
if (skipOcSdkValidation !== undefined && skipOcSdkValidation) {
return Promise.all([this.validateOpenShiftAccess(), this.validateZosCloudBrokerInstallation(), this.validateNamespaceExist()]).then(() => {
return Promise.all([this.validateOpenShiftAccess(), this.validateZosCloudBrokerInstallation(), this.validateNamespaceExists()]).then(() => {
return setContext(this.loggedIntoOpenShift, this.zosCloudBrokerInstalled, undefined, undefined, skipRefresh, this.validNamespace);
});
} else {
return Promise.all([this.validateOcSDKInstallation(), this.validateOpenShiftAccess(), this.validateZosCloudBrokerInstallation(), this.determinateOcSdkIsOutdated(), this.validateNamespaceExist()]).then(() => {
return Promise.all([this.validateOcSDKInstallation(), this.validateOpenShiftAccess(), this.validateZosCloudBrokerInstallation(), this.determinateOcSdkIsOutdated(), this.validateNamespaceExists()]).then(() => {
return setContext(this.loggedIntoOpenShift, this.zosCloudBrokerInstalled, this.ocSdkInstalled, this.ocSdkOutdated, skipRefresh, this.validNamespace);
});
}
Expand Down Expand Up @@ -128,32 +128,35 @@ export class Session {
return false;
})
.catch(e => {
console.log("Log in to an OpenShift Cluster to use this extension: " + JSON.stringify(e));
vscode.window.showInformationMessage("Log in to an OpenShift Cluster to use this extension: " + JSON.stringify(e));
this.loggedIntoOpenShift = false;
return false;
});

// Cancel request after 5 seconds without a response from the getNamespaceList request.
// This usually implies a connectivity issue with OpenShift, which could take a minute or more
// before receiving the timeout response.
const timeout: Promise<boolean> = new Promise(resolve => {
setTimeout(() => {
let timeout: NodeJS.Timeout | undefined = undefined;
const timeoutPromise: Promise<boolean> = new Promise(resolve => {
timeout = setTimeout(() => {
vscode.window.showWarningMessage("Connection timed out... Please validate the connectivity to OpenShift");
resolve(false);
}, 5000);
});

const done = Promise.race([result, timeout])
const done = Promise.race([result, timeoutPromise])
.then(value => {
if (value === false) {
this.loggedIntoOpenShift = false;
} else {
this.loggedIntoOpenShift = true;
}
this.loggedIntoOpenShift = Boolean(value);
return value;
})
.catch(e => {
this.loggedIntoOpenShift = false;
return false;
})
.finally(() => {
if (timeout) {
clearTimeout(timeout);
}
});
return done;
}
Expand All @@ -162,7 +165,7 @@ export class Session {
* Validates the namespace exists
* @returns - A promise containing a boolean, returning true if the namespace exist
*/
async validateNamespaceExist(): Promise<boolean> {
async validateNamespaceExists(): Promise<boolean> {
const k8s = new KubernetesObj();
return k8s
.validateNamespaceExists()
Expand Down
7 changes: 3 additions & 4 deletions src/utilities/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,10 +519,9 @@ export async function requestInitOperatorCollectionInfo(): Promise<string[] | un
const offlineInstallTitle = "Will this collection be executed in an offline environment [y/n]?";

const validateStringLettersAndNumberOnly = (text: string): boolean => {
const ocLoginArgs = text.trimStart();
const validValuesRegex = /^[a-zA-Z0-9]+$/;
const isvalid = !validValuesRegex.test(text?.trimStart());
return isvalid;
const validInputRegex = /(?!^\d+$)^[a-zA-Z0-9]+$/;
const didFailRegex = !validInputRegex.test(text.trim());
return didFailRegex;
};

const collectionName = await vscode.window.showInputBox({
Expand Down