From 853fb5a6ffd002eda76e3aadd0b52355779e556d Mon Sep 17 00:00:00 2001 From: David Thompson Date: Wed, 12 Apr 2023 11:19:36 -0400 Subject: [PATCH] If cluster is not up during login, pick new URL When the user is attempting to login to a cluster, check if the cluster is accessible before prompting for credentials. To check if the cluster is accessible, send a GET request to the cluster API URL; if the API endpoint cannot be found: - if the URL appears to be a CRC api URL, offer to start CRC - if the URL appears to be a Dev Sandbox URL, link to the information page on Dev Sandbox - otherwise, display a warning message and return to the step where the user inputs the cluster URL. This means that if the user tries to login to a cluster that is not running, they don't have to click through the rest of the inputs before receiving this message. Also, if the cluster is not available since the user mistyped the URL, they have the chance to type it in again. Fixes #709 Signed-off-by: David Thompson --- src/openshift/cluster.ts | 70 ++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/src/openshift/cluster.ts b/src/openshift/cluster.ts index 833124f36..0b0ab5d2a 100644 --- a/src/openshift/cluster.ts +++ b/src/openshift/cluster.ts @@ -3,19 +3,20 @@ * Licensed under the MIT License. See LICENSE file in the project root for license information. *-----------------------------------------------------------------------------------------------*/ -import { window, commands, env, QuickPickItem, ExtensionContext, Terminal, Uri, workspace, WebviewPanel, Progress as VProgress, QuickInputButton, ThemeIcon, QuickPickItemButtonEvent } from 'vscode'; +import { KubernetesObject } from '@kubernetes/client-node'; +import { ExtensionContext, QuickInputButton, QuickPickItem, QuickPickItemButtonEvent, Terminal, ThemeIcon, Uri, Progress as VProgress, WebviewPanel, commands, env, window, workspace } from 'vscode'; +import { CliChannel, CliExitData } from '../cli'; import { Command } from '../odo/command'; -import OpenShiftItem, { clusterRequired } from './openshiftItem'; -import { CliExitData, CliChannel } from '../cli'; import { TokenStore } from '../util/credentialManager'; -import { KubeConfigUtils } from '../util/kubeUtils'; import { Filters } from '../util/filters'; -import { Progress } from '../util/progress'; +import { KubeConfigUtils } from '../util/kubeUtils'; import { Platform } from '../util/platform'; +import { Progress } from '../util/progress'; import { WindowUtil } from '../util/windowUtils'; -import { vsCommand, VsCommandError } from '../vscommand'; +import { VsCommandError, vsCommand } from '../vscommand'; import ClusterViewLoader from '../webview/cluster/clusterViewLoader'; -import { KubernetesObject } from '@kubernetes/client-node'; +import OpenShiftItem, { clusterRequired } from './openshiftItem'; +import fetch = require('make-fetch-happen'); interface Versions { 'openshift_version': string; @@ -275,9 +276,60 @@ export class Cluster extends OpenShiftItem { if (response !== 'Yes') return null; - const clusterURL = await Cluster.getUrl(); + let clusterIsUp = false; + let clusterURL: string; - if (!clusterURL) return null; + do { + clusterURL = await Cluster.getUrl(); + + if (!clusterURL) return null; + + try { + await fetch(`${clusterURL}/api`, { + // disable cert checking. crc uses a self-signed cert, + // which means this request will always fail on crc unless cert checking is disabled + strictSSL: false + }); + // since the fetch didn't throw an exception, + // a route to the cluster is available, + // so it's running + clusterIsUp = true; + } catch (e) { + const clusterURLObj = new URL(clusterURL); + if (clusterURLObj.hostname === 'api.crc.testing') { + const startCrc = 'Start OpenShift Local'; + const promptResponse = await window.showWarningMessage( + 'The cluster appears to be a OpenShift Local cluster, but it isn\'t running', + 'Use a different cluster', + startCrc, + ); + if (promptResponse === startCrc){ + await commands.executeCommand('openshift.explorer.addCluster', 'crc'); + // no point in continuing with the wizard, + // it will take the cluster a few minutes to stabilize + return null; + } + } else if (/api\.sandbox-.*openshiftapps\.com/.test(clusterURLObj.hostname)) { + const devSandboxSignup = 'Sign up for OpenShift Dev Sandbox'; + const promptResponse = await window.showWarningMessage( + 'The cluster appears to be a OpenShift Dev Sandbox cluster, but it isn\'t running', + 'Use a different cluster', + devSandboxSignup, + ); + if (promptResponse === devSandboxSignup){ + await commands.executeCommand('openshift.explorer.addCluster', 'sandbox'); + // no point in continuing with the wizard, + // the user needs to sign up for the service + return null; + } + } else { + void window.showWarningMessage( + 'Unable to contact the cluster. Is it running and accessible?', + ); + } + + } + } while (!clusterIsUp); const loginActions = [ {