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

Fix login to sandbox workflow #4109

Merged
merged 1 commit into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"lodash": "^4.17.21",
"make-fetch-happen": "^13.0.1",
"mkdirp": "^3.0.1",
"portfinder": "^1.0.32",
"rxjs": "^7.8.1",
"semver": "^7.6.1",
"shelljs": "^0.8.5",
Expand Down Expand Up @@ -157,7 +158,6 @@
"mocha": "^10.4.0",
"mocha-jenkins-reporter": "^0.4.7",
"npm-run-all": "^4.1.5",
"portfinder": "^1.0.32",
"prettier": "^3.2.5",
"pretty-bytes": "^6.1.1",
"proxyquire": "^2.1.3",
Expand Down
6 changes: 3 additions & 3 deletions src/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ import { HelmRepo } from './helm/helmChartType';
import { Oc } from './oc/ocWrapper';
import { Component } from './openshift/component';
import { getServiceKindStubs } from './openshift/serviceHelpers';
import { PortForward } from './port-forward';
import { KubeConfigUtils, getKubeConfigFiles, getNamespaceKind } from './util/kubeUtils';
import { LoginUtil } from './util/loginUtil';
import { Platform } from './util/platform';
import { Progress } from './util/progress';
import { FileContentChangeNotifier, WatchUtil } from './util/watch';
import { vsCommand } from './vscommand';
import { CustomResourceDefinitionStub } from './webview/common/createServiceTypes';
import { OpenShiftTerminalManager } from './webview/openshift-terminal/openShiftTerminal';
import { LoginUtil } from './util/loginUtil';
import { PortForward } from './port-forward';

type ExplorerItem = KubernetesObject | Helm.HelmRelease | Context | TreeItem | OpenShiftObject | HelmRepo;

Expand Down Expand Up @@ -164,7 +164,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
void commands.executeCommand('setContext', 'isLoggedIn', true);
return {
contextValue: 'openshift.k8sContext',
label: this.kubeConfig.getCluster(element.cluster).server,
label: this.kubeConfig.getCluster(element.cluster)?.server,
collapsibleState: TreeItemCollapsibleState.Collapsed,
iconPath: path.resolve(__dirname, '../../images/context/cluster-node.png')
};
Expand Down
50 changes: 4 additions & 46 deletions src/openshift/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

import { KubernetesObject } from '@kubernetes/client-node';
import { Cluster as KcuCluster, Context as KcuContext } from '@kubernetes/client-node/dist/config_types';
import * as fs from 'fs/promises';
import * as YAML from 'js-yaml';
import * as https from 'https';
import { ExtensionContext, QuickInputButtons, QuickPickItem, QuickPickItemButtonEvent, ThemeIcon, Uri, commands, env, window, workspace } from 'vscode';
import { CommandText } from '../base/command';
import { CliChannel } from '../cli';
Expand All @@ -17,14 +16,13 @@ import * as NameValidator from '../openshift/nameValidator';
import { TokenStore } from '../util/credentialManager';
import { Filters } from '../util/filters';
import { inputValue, quickBtn } from '../util/inputValue';
import { KubeConfigUtils, getKubeConfigFiles } from '../util/kubeUtils';
import { KubeConfigUtils } from '../util/kubeUtils';
import { LoginUtil } from '../util/loginUtil';
import { Platform } from '../util/platform';
import { Progress } from '../util/progress';
import { VsCommandError, vsCommand } from '../vscommand';
import { OpenShiftTerminalManager } from '../webview/openshift-terminal/openShiftTerminal';
import OpenShiftItem, { clusterRequired } from './openshiftItem';
import * as https from 'https';

export interface QuickPickItemExt extends QuickPickItem {
name: string,
Expand Down Expand Up @@ -1006,9 +1004,6 @@ export class Cluster extends OpenShiftItem {

try {
await Oc.Instance.loginWithToken(clusterURL, ocToken, abortController);
if (Cluster.isOpenShiftSandbox(clusterURL)) {
await Cluster.installPipelineUserContext();
}
return Cluster.loginMessage(clusterURL);
} catch (error) {
if (abortController?.signal.aborted) return null;
Expand Down Expand Up @@ -1041,7 +1036,8 @@ export class Cluster extends OpenShiftItem {
apiEndpointUrl: string,
oauthRequestTokenUrl: string,
): Promise<string | null> {
const clipboard = await Cluster.readFromClipboard();
// for whatever reason the token is padded with spaces at the beginning and end when copied from the website
const clipboard = (await Cluster.readFromClipboard()).trim();
if (!clipboard) {
const choice = await window.showErrorMessage(
'Cannot parse token in clipboard. Please click `Get token` button below, copy token into clipboard and press `Login to Sandbox` button again.',
Expand All @@ -1055,44 +1051,6 @@ export class Cluster extends OpenShiftItem {
return Cluster.tokenLogin(apiEndpointUrl, true, clipboard);
}

static async installPipelineUserContext(): Promise<void> {
const kcu = new KubeConfigUtils();
const kcFiles = getKubeConfigFiles();
if (kcFiles.length === 0) {
throw new Error('Could not locate Kube Config when trying to replace OpenShift Sandbox token with a longer-lived token');
}
const kcPath = kcFiles[0];
const kcActual = YAML.load((await fs.readFile(kcPath)).toString('utf-8')) as {
users: { name: string; user: { token: string } }[];
contexts: {
context: { cluster: string; user: string; namespace: string };
name: string;
}[];
'current-context': string;
clusters: object[];
};

const currentCtx = kcu.getCurrentContext();
const currentCtxObj = kcActual.contexts.find(ctx => ctx.name === currentCtx);
const sandboxUser = currentCtxObj.context.user;
const sandboxUserObj = kcActual.users.find(user => user.name === sandboxUser);

const serviceAccounts = await Oc.Instance.getKubernetesObjects('ServiceAccount');
const pipelineServiceAccount = serviceAccounts.find(serviceAccount => serviceAccount.metadata.name === 'pipeline');
if (!pipelineServiceAccount) {
return;
}
const secrets = await Oc.Instance.getKubernetesObjects('Secret');
const pipelineTokenSecret = secrets.find((secret) => secret.metadata.name.startsWith('pipeline-token')) as any;
const pipelineToken = Buffer.from(pipelineTokenSecret.data.token, 'base64').toString();

sandboxUserObj.user = {
token: pipelineToken
}

await fs.writeFile(kcPath, YAML.dump(kcActual, { lineWidth: Number.POSITIVE_INFINITY }));
}

static async loginUsingClipboardInfo(dashboardUrl: string): Promise<string | null> {
const clipboard = await Cluster.readFromClipboard();
if (!NameValidator.ocLoginCommandMatches(clipboard)) {
Expand Down
25 changes: 22 additions & 3 deletions src/webview/cluster/clusterViewLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
import { ChildProcess, spawn } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import { clearInterval } from 'timers';
import * as vscode from 'vscode';
import { CommandText } from '../../base/command';
import { Oc } from '../../oc/ocWrapper';
import { Cluster } from '../../openshift/cluster';
import { createSandboxAPI } from '../../openshift/sandbox';
import { ExtCommandTelemetryEvent } from '../../telemetry';
import { ChildProcessUtil } from '../../util/childProcessUtil';
import { ExtensionID } from '../../util/constants';
import { KubeConfigUtils } from '../../util/kubeUtils';
import { vsCommand } from '../../vscommand';
import { loadWebviewHtml } from '../common-ext/utils';
import { OpenShiftTerminalManager } from '../openshift-terminal/openShiftTerminal';
Expand Down Expand Up @@ -186,6 +189,22 @@ async function clusterEditorMessageListener (event: any ): Promise<any> {
const result = await Cluster.loginUsingClipboardToken(event.payload.apiEndpointUrl, event.payload.oauthRequestTokenUrl);
if (result) void vscode.window.showInformationMessage(`${result}`);
telemetryEventLoginToSandbox.send();
const timeout = setInterval(() => {
const currentUser = new KubeConfigUtils().getCurrentUser();
if (currentUser) {
clearInterval(timeout);
const projectPrefix = currentUser.name.substring(
0,
currentUser.name.indexOf('/'),
);
void Oc.Instance.getProjects().then((projects) => {
const userProject = projects.find((project) =>
project.name.includes(projectPrefix),
);
void Oc.Instance.setProject(userProject.name);
});
}
}, 1000);
} catch (err) {
void vscode.window.showErrorMessage(err.message);
telemetryEventLoginToSandbox.sendError('Login into Sandbox Cluster failed.');
Expand All @@ -201,9 +220,9 @@ async function clusterEditorMessageListener (event: any ): Promise<any> {
async function pollClipboard(signupStatus) {
const oauthInfo = await sandboxAPI.getOauthServerInfo(signupStatus.apiEndpoint);
while (panel) {
const previousContent = await vscode.env.clipboard.readText();
const previousContent = (await vscode.env.clipboard.readText()).trim();
await new Promise(r => setTimeout(r, 500));
const currentContent = await vscode.env.clipboard.readText();
const currentContent = (await vscode.env.clipboard.readText()).trim();
if (previousContent && previousContent !== currentContent) {
let errCode = '';
if (!Cluster.validateLoginToken(currentContent)){
Expand Down Expand Up @@ -359,7 +378,7 @@ export default class ClusterViewLoader {
}

static async loadView(title: string): Promise<vscode.WebviewPanel> {
const localResourceRoot = vscode.Uri.file(path.join(ClusterViewLoader.extensionPath, 'out', 'cluster', 'app'));
const localResourceRoot = vscode.Uri.file(path.join(ClusterViewLoader.extensionPath, 'out'));
if (panel) {
// If we already have a panel, show it in the target column
panel.reveal(vscode.ViewColumn.One);
Expand Down
Loading