Skip to content

Commit be7223c

Browse files
committed
Add/Remove registry commands added to ComponentTypes View
This PR fixes #2005. Signed-off-by: Denis Golovin dgolovin@redhat.com
1 parent 00637eb commit be7223c

File tree

4 files changed

+149
-3
lines changed

4 files changed

+149
-3
lines changed

package.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,20 @@
838838
"light": "images/title/light/icon-refresh.svg"
839839
}
840840
},
841+
{
842+
"command": "openshift.componentTypesView.registry.add",
843+
"title": "Add Registry",
844+
"category": "OpenShift",
845+
"icon": {
846+
"dark": "images/title/dark/add-cluster.svg",
847+
"light": "images/title/light/add-cluster.svg"
848+
}
849+
},
850+
{
851+
"command": "openshift.componentTypesView.registry.remove",
852+
"title": "Remove",
853+
"category": "OpenSift"
854+
},
841855
{
842856
"command": "openshift.welcome",
843857
"title": "Welcome",
@@ -1111,9 +1125,22 @@
11111125
{
11121126
"command": "openshift.component.revealContextInExplorer",
11131127
"when": "false"
1128+
},
1129+
{
1130+
"command": "openshift.componentTypesView.registry.add",
1131+
"when": "false"
1132+
},
1133+
{
1134+
"command": "openshift.componentTypesView.registry.remove",
1135+
"when": "false"
11141136
}
11151137
],
11161138
"view/title": [
1139+
{
1140+
"command": "openshift.componentTypesView.registry.add",
1141+
"when": "view == openshiftComponentTypesView",
1142+
"group": "navigation"
1143+
},
11171144
{
11181145
"command": "openshift.componentTypesView.refresh",
11191146
"when": "view == openshiftComponentTypesView",
@@ -1495,6 +1522,10 @@
14951522
"when": "view == openshiftComponentTypesView && viewItem == s2iImageStreamTag || viewItem == devfileStarterProject || viewItem == devfileComponentType",
14961523
"group": "0@0"
14971524
},
1525+
{
1526+
"command": "openshift.componentTypesView.registry.remove",
1527+
"when": "view == openshiftComponentTypesView && viewItem == devfileRegistry"
1528+
},
14981529
{
14991530
"command": "openshift.component.revealInExplorer",
15001531
"when": "view == openshiftComponentsView && viewItem == openshift.component"

src/componentTypesView.ts

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import * as path from 'path';
1818
import { CliExitData } from './cli';
1919
import {
2020
getInstance,
21-
Odo
21+
Odo,
22+
OdoImpl
2223
} from './odo';
2324
import { Command } from './odo/command';
2425
import {
@@ -44,6 +45,7 @@ import { vsCommand, VsCommandError } from './vscommand';
4445
import { Cluster } from '@kubernetes/client-node/dist/config_types';
4546
import { KubeConfig } from '@kubernetes/client-node';
4647
import { Platform } from './util/platform';
48+
import * as validator from 'validator';
4749

4850
type ExampleProject = SampleProject | StarterProject;
4951
type ComponentType = DevfileComponentType | ImageStreamTag | ExampleProject | Cluster | Registry;
@@ -104,6 +106,7 @@ export class ComponentTypesView implements TreeDataProvider<ComponentType> {
104106
if (isRegistry(element)) {
105107
return {
106108
label: element.Name,
109+
contextValue: ContextType.DEVFILE_REGISTRY,
107110
tooltip: `Devfile Registry\nName: ${element.Name}\nURL: ${element.URL}`,
108111
collapsibleState: TreeItemCollapsibleState.Collapsed,
109112
}
@@ -182,6 +185,21 @@ export class ComponentTypesView implements TreeDataProvider<ComponentType> {
182185
return data;
183186
}
184187

188+
addRegistry(newRegistry: Registry): void {
189+
this.registries.push(newRegistry);
190+
this.refresh(false);
191+
this.reveal(newRegistry);
192+
193+
}
194+
195+
removeRegistry(targetRegistry: Registry): void {
196+
this.registries.splice(
197+
this.registries.findIndex((registry) => registry.Name === targetRegistry.Name),
198+
1
199+
);
200+
this.refresh(false);
201+
}
202+
185203
private async getRegistries(): Promise<Registry[]> {
186204
if(!this.registries) {
187205
this.registries = await this.odo.getRegistries();
@@ -239,8 +257,14 @@ export class ComponentTypesView implements TreeDataProvider<ComponentType> {
239257
return undefined;
240258
}
241259

242-
refresh(): void {
243-
this.registries = undefined;
260+
reveal(item: Registry): void {
261+
this.treeView.reveal(item);
262+
}
263+
264+
refresh(cleanCache = true): void {
265+
if (cleanCache) {
266+
this.registries = undefined;
267+
}
244268
this.onDidChangeTreeDataEmitter.fire();
245269
}
246270

@@ -289,4 +313,69 @@ export class ComponentTypesView implements TreeDataProvider<ComponentType> {
289313
return 'Cannot find sample project repository url';
290314
}
291315
}
316+
317+
@vsCommand('openshift.componentTypesView.registry.add')
318+
public static async addRegistryCmd(): Promise<void> {
319+
// ask for registry
320+
const regName = await window.showInputBox({
321+
prompt: 'Provide registry name to display in the view',
322+
placeHolder: 'Registry Name',
323+
validateInput: async (value) => {
324+
const trimmedValue = value.trim();
325+
if (trimmedValue.length === 0) {
326+
return 'Registry name cannot be empty'
327+
}
328+
if (!validator.matches(trimmedValue, '^[a-zA-Z0-9]+$')) {
329+
return 'Registry name can have only alphabet characters and numbers';
330+
}
331+
const registries = await ComponentTypesView.instance.getRegistries();
332+
if(registries.find((registry) => registry.Name === value)) {
333+
return `Registry name '${value}' is already used`;
334+
}
335+
}
336+
});
337+
338+
if (!regName) return null;
339+
340+
const regURL = await window.showInputBox({ignoreFocusOut: true,
341+
prompt: 'Provide registry URL to display in the view',
342+
placeHolder: 'Registry URL',
343+
validateInput: async (value) => {
344+
const trimmedValue = value.trim();
345+
if (!validator.isURL(trimmedValue)) {
346+
return 'Entered URL is invalid'
347+
}
348+
const registries = await ComponentTypesView.instance.getRegistries();
349+
if(registries.find((registry) => registry.URL === value)) {
350+
return `Registry with entered URL '${value}' already exists`;
351+
}
352+
}
353+
});
354+
355+
if (!regURL) return null;
356+
357+
const secure = await window.showQuickPick(['Yes', 'No'], {
358+
placeHolder: 'Is it a secure registry?'
359+
});
360+
361+
if (!secure) return null;
362+
363+
let token: string;
364+
if (secure === 'Yes') {
365+
token = await window.showInputBox({placeHolder: 'Token to access the registry'});
366+
if (!token) return null;
367+
}
368+
369+
const newRegistry = await OdoImpl.Instance.addRegistry(regName, regURL, token);
370+
ComponentTypesView.instance.addRegistry(newRegistry);
371+
}
372+
373+
@vsCommand('openshift.componentTypesView.registry.remove')
374+
public static async removeRegistry(registry: Registry): Promise<void> {
375+
const yesNo = await window.showInformationMessage(`Remove registry '${registry.Name}'?`, 'Yes', 'No');
376+
if (yesNo === 'Yes') {
377+
await OdoImpl.Instance.removeRegistry(registry.Name);
378+
ComponentTypesView.instance.removeRegistry(registry);
379+
}
380+
}
292381
}

src/odo.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ export interface Odo {
364364
loadItems<I>(result: cliInstance.CliExitData, fetch: (data) => I[]): I[];
365365
getRegistries(): Promise<Registry[]>;
366366
readonly subject: Subject<OdoEvent>;
367+
addRegistry(name: string, url: string, token: string): Promise<Registry>;
368+
removeRegistry(name: string): Promise<void>;
367369
}
368370

369371
class OdoModel {
@@ -1113,6 +1115,18 @@ export class OdoImpl implements Odo {
11131115
return this.loadItemsFrom<RegistryList, Registry>(result, (data) => data.registries);
11141116
}
11151117

1118+
public async addRegistry(name: string, url: string, token: string): Promise<Registry> {
1119+
await this.execute(Command.addRegistry(name, url, token));
1120+
return {
1121+
Name: name,
1122+
Secure: true,
1123+
URL: url
1124+
};
1125+
}
1126+
1127+
public async removeRegistry(name: string): Promise<void> {
1128+
await this.execute(Command.removeRegistry(name));
1129+
}
11161130
}
11171131

11181132
export function getInstance(): Odo {

src/odo/command.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ export class Command {
141141
return new CommandText('odo registry list -o json');
142142
}
143143

144+
static addRegistry(name: string, url: string, token: string): CommandText {
145+
const cTxt = new CommandText('odo registry add', `${name} ${url}`);
146+
if (token) {
147+
cTxt.addOption(new CommandOption('--token', token));
148+
}
149+
return cTxt;
150+
}
151+
152+
static removeRegistry(name: string): CommandText {
153+
return new CommandText('odo registry delete', name, [new CommandOption('-f')]);
154+
}
155+
144156
static listCatalogComponents(): CommandText {
145157
return new CommandText('odo catalog list components');
146158
}

0 commit comments

Comments
 (0)