Skip to content

Commit 8d21075

Browse files
mohitsumandgolovin
authored andcommitted
Provide cluster and usernames from k8 config for login (#903)
1 parent d88c1a6 commit 8d21075

File tree

8 files changed

+315
-351
lines changed

8 files changed

+315
-351
lines changed

package-lock.json

+169-292
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+11-11
Original file line numberDiff line numberDiff line change
@@ -673,17 +673,17 @@
673673
"@types/fs-extra": "^5.0.5",
674674
"@types/js-yaml": "^3.12.1",
675675
"@types/mkdirp": "^0.5.2",
676-
"@types/mocha": "^5.2.6",
677-
"@types/node": "^11.13.8",
676+
"@types/mocha": "^5.2.7",
677+
"@types/node": "^12.0.10",
678678
"@types/request": "^2.48.1",
679679
"@types/shelljs": "^0.8.5",
680680
"@types/sinon": "^5.0.7",
681681
"@types/sinon-chai": "^3.2.2",
682682
"@types/string-format": "^2.0.0",
683683
"@types/tmp": "0.0.34",
684-
"@types/validator": "^10.11.0",
684+
"@types/validator": "^10.11.1",
685685
"chai": "^4.2.0",
686-
"codecov": "^3.3.0",
686+
"codecov": "^3.5.0",
687687
"decache": "^4.5.1",
688688
"glob": "^7.1.3",
689689
"istanbul": "^0.4.5",
@@ -694,13 +694,13 @@
694694
"sinon": "^7.3.2",
695695
"sinon-chai": "^3.3.0",
696696
"tmp": "0.0.33",
697-
"tslint": "^5.16.0",
698-
"typescript": "^3.4.5",
699-
"vscode": "^1.1.33",
697+
"tslint": "^5.18.0",
698+
"typescript": "^3.5.2",
699+
"vscode": "^1.1.34",
700700
"walker": "^1.0.7"
701701
},
702702
"dependencies": {
703-
"@kubernetes/client-node": "^0.8.2",
703+
"@kubernetes/client-node": "^0.10.2",
704704
"binary-search": "^1.3.5",
705705
"byline": "^5.0.0",
706706
"event-stream": "3.3.4",
@@ -710,15 +710,15 @@
710710
"hasha": "^5.0.0",
711711
"js-yaml": "^3.13.1",
712712
"mkdirp": "^0.5.1",
713-
"open": "^6.2.0",
713+
"open": "^6.3.0",
714714
"request": "^2.88.0",
715715
"request-progress": "^3.0.0",
716-
"semver": "^6.0.0",
716+
"semver": "^6.1.1",
717717
"shelljs": "^0.8.3",
718718
"string-format": "^2.0.0",
719719
"targz": "^1.0.1",
720720
"unzip-stream": "^0.3.0",
721-
"validator": "^10.11.0",
721+
"validator": "^11.0.0",
722722
"vscode-kubernetes-tools-api": "0.0.7"
723723
}
724724
}

src/cli.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class Cli implements ICli {
3737
opts.maxBuffer = 2*1024*1024;
3838
}
3939
childProcess.exec(cmd, opts, (error: ExecException, stdout: string, stderr: string) => {
40-
const stdoutFiltered = stdout.replace(/---[\s\S]*$/g, '').trim()
40+
const stdoutFiltered = stdout.replace(/---[\s\S]*$/g, '').trim();
4141
this.odoChannel.print(stdoutFiltered);
4242
this.odoChannel.print(stderr);
4343
// do not reject it here, because caller in some cases need the error and the streams

src/k8s/deployment.ts

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Build implements ClusterExplorerV1.Node, ClusterExplorerV1.ClusterExplorer
2929
readonly kind: ClusterExplorerV1.ResourceKind = this.resourceKind;
3030
public id: string;
3131
public resourceId: string;
32+
// tslint:disable-next-line:variable-name
3233
constructor(readonly namespace: string, readonly name: string, readonly number: number, readonly metadata?: any) {
3334
this.id = this.resourceId = `build/${this.name}`;
3435
}

src/openshift/cluster.ts

+55-14
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,30 @@
55

66
import { OpenShiftObject, Command } from "../odo";
77
import { OpenShiftItem } from './openshiftItem';
8-
import { window, commands, env } from 'vscode';
8+
import { window, commands, env, QuickPickItem } from 'vscode';
99
import { CliExitData, Cli } from "../cli";
1010
import open = require("open");
1111
import { TokenStore } from "../util/credentialManager";
12+
import { KubeConfigUtils } from '../util/kubeUtils';
1213

14+
15+
class CreateUrlItem implements QuickPickItem {
16+
17+
constructor() { }
18+
19+
get label(): string { return `$(plus) Provide new URL...`; }
20+
get description(): string { return ''; }
21+
22+
}
23+
24+
class CreateUserItem implements QuickPickItem {
25+
26+
constructor() { }
27+
28+
get label(): string { return `$(plus) Add new user...`; }
29+
get description(): string { return ''; }
30+
31+
}
1332
export class Cluster extends OpenShiftItem {
1433

1534
static async logout(): Promise<string> {
@@ -61,13 +80,18 @@ export class Cluster extends OpenShiftItem {
6180
}
6281

6382
static async getUrl(): Promise<string | null> {
83+
const k8sConfig = new KubeConfigUtils();
6484
const clusterURl = await Cluster.getUrlFromClipboard();
65-
return await window.showInputBox({
66-
value: clusterURl,
67-
ignoreFocusOut: true,
68-
prompt: "Provide URL of the cluster to connect",
69-
validateInput: (value: string) => Cluster.validateUrl('Invalid URL provided', value)
70-
});
85+
const createUrl = new CreateUrlItem();
86+
const clusterItems = await k8sConfig.getServers();
87+
const choice = await window.showQuickPick([createUrl, ...clusterItems], {placeHolder: "Provide Cluster URL to connect"});
88+
return (choice.label === createUrl.label) ?
89+
await window.showInputBox({
90+
value: clusterURl,
91+
ignoreFocusOut: true,
92+
prompt: "Provide new Cluster URL to connect",
93+
validateInput: (value: string) => Cluster.validateUrl('Invalid URL provided', value)
94+
}) : choice.label;
7195
}
7296

7397
static async login(): Promise<string> {
@@ -103,25 +127,42 @@ export class Cluster extends OpenShiftItem {
103127
static async credentialsLogin(skipConfirmation: boolean = false): Promise<string> {
104128
let password: string;
105129
const response = await Cluster.requestLoginConfirmation(skipConfirmation);
130+
106131
if (response !== 'Yes') return null;
132+
107133
const clusterURL = await Cluster.getUrl();
134+
108135
if (!clusterURL) return null;
136+
109137
const getUserName = await TokenStore.getUserName();
110-
const username = await window.showInputBox({
111-
ignoreFocusOut: true,
112-
prompt: "Provide Username for basic authentication to the API server",
113-
value: getUserName,
114-
validateInput: (value: string) => Cluster.emptyName('User name cannot be empty', value)
115-
});
138+
const k8sConfig = new KubeConfigUtils();
139+
const users = await k8sConfig.getClusterUsers(clusterURL);
140+
const addUser = new CreateUserItem();
141+
const choice = await window.showQuickPick([addUser, ...users], {placeHolder: "Select username for basic authentication to the API server"});
142+
143+
if (!choice) return null;
144+
145+
const username = (choice.label === addUser.label) ?
146+
await window.showInputBox({
147+
ignoreFocusOut: true,
148+
prompt: "Provide Username for basic authentication to the API server",
149+
value: "",
150+
validateInput: (value: string) => Cluster.emptyName('User name cannot be empty', value)
151+
}) : choice.label;
152+
116153
if (getUserName) password = await TokenStore.getItem('login', username);
154+
117155
if (!username) return null;
156+
118157
const passwd = await window.showInputBox({
119158
ignoreFocusOut: true,
120159
password: true,
121160
prompt: "Provide Password for basic authentication to the API server",
122161
value: password
123162
});
163+
124164
if (!passwd) return null;
165+
125166
return Promise.resolve()
126167
.then(() => Cluster.odo.execute(Command.odoLoginWithUsernamePassword(clusterURL, username, passwd)))
127168
.then((result) => Cluster.save(username, passwd, password, result))
@@ -171,4 +212,4 @@ export class Cluster extends OpenShiftItem {
171212
return Promise.reject(result.stderr);
172213
}
173214
}
174-
}
215+
}

src/openshift/component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ export class Component extends OpenShiftItem {
164164
"For which Component you want to push the changes");
165165
if (!component) return null;
166166
Component.setPushCmd(component.getName(), component.getParent().getName(), component.getParent().getParent().getName());
167-
Component.odo.executeInTerminal(Command.pushComponent(component.getParent().getParent().getName(), component.getParent().getName(), component.getName()))
167+
Component.odo.executeInTerminal(Command.pushComponent(component.getParent().getParent().getName(), component.getParent().getName(), component.getName()));
168168
}
169169

170170
static async lastPush() {

src/util/kubeUtils.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { QuickPickItem } from "vscode";
2+
import { KubeConfig } from '@kubernetes/client-node';
3+
import { User, Cluster } from "@kubernetes/client-node/dist/config_types";
4+
5+
export class KubeConfigUtils extends KubeConfig {
6+
7+
constructor() {
8+
super();
9+
this.loadFromDefault();
10+
};
11+
12+
async getServers(): Promise<QuickPickItem[]> {
13+
const currentCluster = this.getCurrentCluster();
14+
const clusters = this.clusters || [];
15+
return clusters.map((c: any) => ({
16+
label: c.server,
17+
description: currentCluster && c.name === currentCluster.name ? 'Current Context' : ''
18+
}));
19+
}
20+
21+
async getClusterUsers(clusterServer: string): Promise<QuickPickItem[]> {
22+
const currentUser = this.getCurrentUser();
23+
const cluster = this.findCluster(clusterServer);
24+
const users = this.getUsers();
25+
const clusterUsers = users.filter((item) => cluster && item.name.indexOf(cluster.name) > -1);
26+
return clusterUsers.map((u: User) => ({
27+
label: u.name.split('/')[0],
28+
description: u === currentUser ? 'Current Context' : ''
29+
}));
30+
}
31+
32+
findCluster(clusterServer: string): Cluster {
33+
return this.getClusters().find((cluster: Cluster) => cluster.server === clusterServer);
34+
}
35+
}

0 commit comments

Comments
 (0)