Skip to content

Commit d7db511

Browse files
Create route functionality added (#4140)
* create route functionality added * added secure and un secured routes * fix lint issues * fixed lint issues * fixed review comments * fixed mentioned comments * add separate validate name junction for json value
1 parent 315e8fb commit d7db511

File tree

19 files changed

+861
-10
lines changed

19 files changed

+861
-10
lines changed

build/esbuild.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as fs from 'fs/promises';
1111
const webviews = [
1212
'cluster',
1313
'create-service',
14+
'create-route',
1415
'create-component',
1516
'devfile-registry',
1617
'helm-chart',

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,11 @@
807807
"title": "Create Operator-Backed Service",
808808
"category": "OpenShift"
809809
},
810+
{
811+
"command": "openshift.route.create",
812+
"title": "Create Route",
813+
"category": "OpenShift"
814+
},
810815
{
811816
"command": "openshift.deployment.create.fromImageUrl",
812817
"title": "Create Deployment from Container Image URL",
@@ -1626,6 +1631,11 @@
16261631
"when": "view == openshiftProjectExplorer && isLoggedIn && viewItem =~ /openshift.project.*/i && showCreateService",
16271632
"group": "c2"
16281633
},
1634+
{
1635+
"command": "openshift.route.create",
1636+
"when": "view == openshiftProjectExplorer && isLoggedIn && viewItem =~ /openshift.project.*/i && isOpenshiftCluster && showCreateRoute",
1637+
"group": "c2"
1638+
},
16291639
{
16301640
"command": "openshift.deployment.create.fromImageUrl",
16311641
"when": "view == openshiftProjectExplorer && isLoggedIn && viewItem =~ /openshift.project.*/i",

src/explorer.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ import * as Helm from './helm/helm';
2727
import { HelmRepo } from './helm/helmChartType';
2828
import { Oc } from './oc/ocWrapper';
2929
import { Component } from './openshift/component';
30-
import { getServiceKindStubs } from './openshift/serviceHelpers';
30+
import { getServiceKindStubs, getServices } from './openshift/serviceHelpers';
3131
import { PortForward } from './port-forward';
3232
import { KubeConfigUtils, getKubeConfigFiles, getNamespaceKind } from './util/kubeUtils';
3333
import { LoginUtil } from './util/loginUtil';
3434
import { Platform } from './util/platform';
3535
import { Progress } from './util/progress';
3636
import { FileContentChangeNotifier, WatchUtil } from './util/watch';
3737
import { vsCommand } from './vscommand';
38-
import { CustomResourceDefinitionStub } from './webview/common/createServiceTypes';
38+
import { CustomResourceDefinitionStub, K8sResourceKind } from './webview/common/createServiceTypes';
3939
import { OpenShiftTerminalManager } from './webview/openshift-terminal/openShiftTerminal';
4040
import { getOutputFormat, helmfsUri, kubefsUri } from './k8s/vfs/kuberesources.virtualfs';
4141

@@ -355,6 +355,16 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
355355
// operator framework is not installed on cluster; do nothing
356356
}
357357
void commands.executeCommand('setContext', 'showCreateService', serviceKinds.length > 0);
358+
359+
// The 'Create Route' menu visibility
360+
let services: K8sResourceKind[] = [];
361+
try {
362+
services = await getServices();
363+
}
364+
catch (_) {
365+
// operator framework is not installed on cluster; do nothing
366+
}
367+
void commands.executeCommand('setContext', 'showCreateRoute', services.length > 0);
358368
} else if ('kind' in element && element.kind === 'helmContexts') {
359369
const helmRepos = {
360370
kind: 'helmRepos',
@@ -411,6 +421,12 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
411421
name: 'pods'
412422
},
413423
} as OpenShiftObject;
424+
const routes = {
425+
kind: 'routes',
426+
metadata: {
427+
name: 'routes'
428+
},
429+
} as OpenShiftObject;
414430
const statefulSets = {
415431
kind: 'statefulsets',
416432
metadata: {
@@ -456,7 +472,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
456472
result.push(pods,
457473
statefulSets, daemonSets, jobs, cronJobs);
458474
if (isOpenshiftCluster) {
459-
result.push(deploymentConfigs, imageStreams, buildConfigs);
475+
result.push(deploymentConfigs, imageStreams, buildConfigs, routes);
460476
}
461477
} else if ('kind' in element) {
462478
const collectableServices: CustomResourceDefinitionStub[] = await this.getServiceKinds();

src/extension.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export async function activate(extensionContext: ExtensionContext): Promise<unkn
101101
'./openshift/project',
102102
'./openshift/cluster',
103103
'./openshift/service',
104+
'./openshift/route',
104105
'./k8s/console',
105106
'./yamlFileCommands',
106107
'./registriesView',

src/k8s/olm/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,9 @@ export type CapabilityProps<C extends SpecCapability | StatusCapability> = {
352352
value: any;
353353
};
354354

355+
export type Service = {
356+
apiVersion: string;
357+
items: K8sResourceKind[];
358+
}
359+
355360
export type Error = { message: string };

src/k8s/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright (c) Red Hat, Inc. All rights reserved.
33
* Licensed under the MIT License. See LICENSE file in the project root for license information.
44
*-----------------------------------------------------------------------------------------------*/
5-
65
import { KubeConfig } from '@kubernetes/client-node';
76
import { commands, Uri } from 'vscode';
87
import { Oc } from '../oc/ocWrapper';

src/oc/ocWrapper.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { KubeConfigUtils } from '../util/kubeUtils';
1212
import { Platform } from '../util/platform';
1313
import { Project } from './project';
1414
import { ClusterType, KubernetesConsole } from './types';
15+
import validator from 'validator';
1516

1617
/**
1718
* A wrapper around the `oc` CLI tool.
@@ -506,6 +507,38 @@ export class Oc {
506507
});
507508
}
508509

510+
public async createRoute(routeName: string, serviceName: string, hostName: string, path: string, port: { number: string, name: string, protocol: string, targetPort: string },
511+
isSecured: boolean): Promise<string> {
512+
let cmdText: CommandText;
513+
if (isSecured) {
514+
515+
cmdText = new CommandText('oc', `create route edge ${routeName}`, [
516+
new CommandOption('--service', serviceName),
517+
new CommandOption('--port', port.number),
518+
]);
519+
520+
} else {
521+
cmdText = new CommandText('oc', `expose service ${serviceName.trim()}`, [
522+
new CommandOption('--name', routeName),
523+
new CommandOption('--port', port.number),
524+
new CommandOption('--target-port', port.targetPort),
525+
new CommandOption('--protocol', port.protocol)
526+
]);
527+
}
528+
529+
if (!validator.isEmpty(hostName)) {
530+
cmdText.addOption(new CommandOption('--hostname', hostName));
531+
}
532+
533+
if (!validator.isEmpty(path)) {
534+
cmdText.addOption(new CommandOption('--path', path));
535+
}
536+
return await CliChannel.getInstance().executeTool(
537+
cmdText
538+
)
539+
.then((result) => result.stdout);
540+
}
541+
509542
/**
510543
* Changes which project is currently being used.
511544
*

src/openshift/nameValidator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export function validateMatches(message: string, value: string): string | null {
2222
return validator.matches(value, '^[a-z]([-a-z0-9]*[a-z0-9])*$') ? null : message;
2323
}
2424

25+
export function validatePath(message: string, value: string): string | null {
26+
const pathRegx = value.match(/^(\/{1}(?!\/))[A-Za-z0-9/\-_]*(([a-zA-Z]+))?$/);
27+
return pathRegx ? null : message;
28+
}
29+
2530
export function validateFilePath(message: string, value: string): string | null {
2631
const proposedPath = path.parse(value);
2732
return /^devfile\.ya?ml$/i.test(proposedPath.base) ? null : message;

src/openshift/route.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*-----------------------------------------------------------------------------------------------
2+
* Copyright (c) Red Hat, Inc. All rights reserved.
3+
* Licensed under the MIT License. See LICENSE file in the project root for license information.
4+
*-----------------------------------------------------------------------------------------------*/
5+
6+
import { vsCommand } from '../vscommand';
7+
import CreateRouteViewLoader from '../webview/create-route/createRouteViewLoader';
8+
9+
/**
10+
* Wraps commands that are used for interacting with routes.
11+
*/
12+
export class Route {
13+
@vsCommand('openshift.route.create')
14+
static async createNewRoute() {
15+
await CreateRouteViewLoader.loadView();
16+
}
17+
}

src/openshift/serviceHelpers.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Licensed under the MIT License. See LICENSE file in the project root for license information.
44
*-----------------------------------------------------------------------------------------------*/
55

6+
import { K8sResourceKind } from '../k8s/olm/types';
67
import { Oc } from '../oc/ocWrapper';
78
import {
89
ClusterServiceVersion,
@@ -21,3 +22,9 @@ export async function getServiceKindStubs(): Promise<CustomResourceDefinitionStu
2122
return serviceKinds;
2223
});
2324
}
25+
26+
export async function getServices(): Promise<K8sResourceKind[]> {
27+
return (await Oc.Instance.getKubernetesObjects(
28+
'service'
29+
)) as unknown as K8sResourceKind[];
30+
}

0 commit comments

Comments
 (0)