Skip to content
461 changes: 169 additions & 292 deletions package-lock.json

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -673,17 +673,17 @@
"@types/fs-extra": "^5.0.5",
"@types/js-yaml": "^3.12.1",
"@types/mkdirp": "^0.5.2",
"@types/mocha": "^5.2.6",
"@types/node": "^11.13.8",
"@types/mocha": "^5.2.7",
"@types/node": "^12.0.10",
"@types/request": "^2.48.1",
"@types/shelljs": "^0.8.5",
"@types/sinon": "^5.0.7",
"@types/sinon-chai": "^3.2.2",
"@types/string-format": "^2.0.0",
"@types/tmp": "0.0.34",
"@types/validator": "^10.11.0",
"@types/validator": "^10.11.1",
"chai": "^4.2.0",
"codecov": "^3.3.0",
"codecov": "^3.5.0",
"decache": "^4.5.1",
"glob": "^7.1.3",
"istanbul": "^0.4.5",
Expand All @@ -694,13 +694,13 @@
"sinon": "^7.3.2",
"sinon-chai": "^3.3.0",
"tmp": "0.0.33",
"tslint": "^5.16.0",
"typescript": "^3.4.5",
"vscode": "^1.1.33",
"tslint": "^5.18.0",
"typescript": "^3.5.2",
"vscode": "^1.1.34",
"walker": "^1.0.7"
},
"dependencies": {
"@kubernetes/client-node": "^0.8.2",
"@kubernetes/client-node": "^0.10.2",
"binary-search": "^1.3.5",
"byline": "^5.0.0",
"event-stream": "3.3.4",
Expand All @@ -710,15 +710,15 @@
"hasha": "^5.0.0",
"js-yaml": "^3.13.1",
"mkdirp": "^0.5.1",
"open": "^6.2.0",
"open": "^6.3.0",
"request": "^2.88.0",
"request-progress": "^3.0.0",
"semver": "^6.0.0",
"semver": "^6.1.1",
"shelljs": "^0.8.3",
"string-format": "^2.0.0",
"targz": "^1.0.1",
"unzip-stream": "^0.3.0",
"validator": "^10.11.0",
"validator": "^11.0.0",
"vscode-kubernetes-tools-api": "0.0.7"
}
}
2 changes: 1 addition & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Cli implements ICli {
opts.maxBuffer = 2*1024*1024;
}
childProcess.exec(cmd, opts, (error: ExecException, stdout: string, stderr: string) => {
const stdoutFiltered = stdout.replace(/---[\s\S]*$/g, '').trim()
const stdoutFiltered = stdout.replace(/---[\s\S]*$/g, '').trim();
this.odoChannel.print(stdoutFiltered);
this.odoChannel.print(stderr);
// do not reject it here, because caller in some cases need the error and the streams
Expand Down
1 change: 1 addition & 0 deletions src/k8s/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Build implements ClusterExplorerV1.Node, ClusterExplorerV1.ClusterExplorer
readonly kind: ClusterExplorerV1.ResourceKind = this.resourceKind;
public id: string;
public resourceId: string;
// tslint:disable-next-line:variable-name
constructor(readonly namespace: string, readonly name: string, readonly number: number, readonly metadata?: any) {
this.id = this.resourceId = `build/${this.name}`;
}
Expand Down
70 changes: 54 additions & 16 deletions src/openshift/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,29 @@

import { OpenShiftObject, Command } from "../odo";
import { OpenShiftItem } from './openshiftItem';
import { window, commands, env } from 'vscode';
import { window, commands, env, QuickPickItem } from 'vscode';
import { CliExitData, Cli } from "../cli";
import open = require("open");
import { TokenStore } from "../util/credentialManager";
import { getClusters, getUsers } from '../util/kubeUtils';

class CreateUrlItem implements QuickPickItem {

constructor() { }

get label(): string { return `$(plus) Provide new URL...`; }
get description(): string { return ''; }

}

class CreateUserItem implements QuickPickItem {

constructor() { }

get label(): string { return `$(plus) Add new user...`; }
get description(): string { return ''; }

}
export class Cluster extends OpenShiftItem {

static async logout(): Promise<string> {
Expand Down Expand Up @@ -62,12 +80,16 @@ export class Cluster extends OpenShiftItem {

static async getUrl(): Promise<string | null> {
const clusterURl = await Cluster.getUrlFromClipboard();
return await window.showInputBox({
value: clusterURl,
ignoreFocusOut: true,
prompt: "Provide URL of the cluster to connect",
validateInput: (value: string) => Cluster.validateUrl('Invalid URL provided', value)
});
const createUrl = new CreateUrlItem();
const clusterItems = await getClusters();
const choice = await window.showQuickPick([createUrl, ...clusterItems], {placeHolder: "Provide Cluster URL to connect"});
return (choice.label === createUrl.label) ?
await window.showInputBox({
value: clusterURl,
ignoreFocusOut: true,
prompt: "Provide new Cluster URL to connect",
validateInput: (value: string) => Cluster.validateUrl('Invalid URL provided', value)
}) : choice.label;
}

static async login(): Promise<string> {
Expand Down Expand Up @@ -103,27 +125,43 @@ export class Cluster extends OpenShiftItem {
static async credentialsLogin(skipConfirmation: boolean = false): Promise<string> {
let password: string;
const response = await Cluster.requestLoginConfirmation(skipConfirmation);

if (response !== 'Yes') return null;

const clusterURL = await Cluster.getUrl();

if (!clusterURL) return null;

const getUserName = await TokenStore.getUserName();
const username = await window.showInputBox({
ignoreFocusOut: true,
prompt: "Provide Username for basic authentication to the API server",
value: getUserName,
validateInput: (value: string) => Cluster.emptyName('User name cannot be empty', value)
});
const users = await getUsers(clusterURL);
const addUser = new CreateUserItem();
const choice = await window.showQuickPick([addUser, ...users], {placeHolder: "Select username for basic authentication to the API server"});

if (!choice) return null;

const username = (choice.label === addUser.label) ?
await window.showInputBox({
ignoreFocusOut: true,
prompt: "Provide Username for basic authentication to the API server",
value: getUserName,
validateInput: (value: string) => Cluster.emptyName('User name cannot be empty', value)
}) : choice.label;

if (getUserName) password = await TokenStore.getItem('login', username);

if (!username) return null;

const passwd = await window.showInputBox({
ignoreFocusOut: true,
password: true,
prompt: "Provide Password for basic authentication to the API server",
value: password
});

if (!passwd) return null;

return Promise.resolve()
.then(() => Cluster.odo.execute(Command.odoLoginWithUsernamePassword(clusterURL, username, passwd)))
.then(() => Cluster.odo.execute(Command.odoLoginWithUsernamePassword(clusterURL.replace(/-/g, '.'), username, passwd)))
.then((result) => Cluster.save(username, passwd, password, result))
.then((result) => Cluster.loginMessage(clusterURL, result))
.catch((error) => Promise.reject(`Failed to login to cluster '${clusterURL}' with '${error}'!`));
Expand Down Expand Up @@ -157,7 +195,7 @@ export class Cluster extends OpenShiftItem {
});
if (!ocToken) return null;
return Promise.resolve()
.then(() => Cluster.odo.execute(Command.odoLoginWithToken(clusterURL, ocToken)))
.then(() => Cluster.odo.execute(Command.odoLoginWithToken(clusterURL.replace(/-/g, '.'), ocToken)))
.then((result) => Cluster.loginMessage(clusterURL, result))
.catch((error) => Promise.reject(`Failed to login to cluster '${clusterURL}' with '${error}'!`));
}
Expand All @@ -171,4 +209,4 @@ export class Cluster extends OpenShiftItem {
return Promise.reject(result.stderr);
}
}
}
}
2 changes: 1 addition & 1 deletion src/openshift/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export class Component extends OpenShiftItem {
"For which Component you want to push the changes");
if (!component) return null;
Component.setPushCmd(component.getName(), component.getParent().getName(), component.getParent().getParent().getName());
Component.odo.executeInTerminal(Command.pushComponent(component.getParent().getParent().getName(), component.getParent().getName(), component.getName()))
Component.odo.executeInTerminal(Command.pushComponent(component.getParent().getParent().getName(), component.getParent().getName(), component.getName()));
}

static async lastPush() {
Expand Down
38 changes: 38 additions & 0 deletions src/util/kubeUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { QuickPickItem } from "vscode";
import { KubeConfig } from '@kubernetes/client-node';

export async function getClusters(): Promise<QuickPickItem[]> {
const kubectlConfig = new KubeConfig();
kubectlConfig.loadFromDefault();
if (!kubectlConfig) {
Comment thread
dgolovin marked this conversation as resolved.
Outdated
return [];
}
const currentContextServer = kubectlConfig.currentContext.split('/')[1];
const clusters = kubectlConfig.clusters || [];
return clusters.map((c) => {
return {
label: c.name,
description: c.name === currentContextServer ? 'Current Context' : ''
};
});
}

export async function getUsers(clusterUrl: string): Promise<QuickPickItem[]> {
const kubectlConfig = new KubeConfig();
kubectlConfig.loadFromDefault();
if (!kubectlConfig) {
Comment thread
dgolovin marked this conversation as resolved.
Outdated
return [];
}
const currentContextUser = kubectlConfig.currentContext.split('/')[2];
return kubectlConfig.users
Comment thread
dgolovin marked this conversation as resolved.
Outdated
.filter((item) => {
return item.name.split('/')[1] === clusterUrl;
})
.map((u) => {
const username = u.name.split('/')[0];
return {
label: username,
description: username === currentContextUser ? 'Current Context' : ''
};
});
}
Loading