Skip to content
This repository has been archived by the owner on Jan 20, 2023. It is now read-only.

Avoid the need to set userland-proxy #58

Merged
merged 9 commits into from
May 14, 2019
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ _testmain.go
*.test
*.prof
.idea/
.vscode/
4 changes: 4 additions & 0 deletions brokers/unified/vscode/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ func (b *brokerImpl) injectRemotePlugin(plugin model.ChePlugin, archivesPaths []
}
plugin = AddExtension(plugin, *pj, b.localhostSidecar)
}

if b.localhostSidecar {
plugin.Endpoints = plugin.Endpoints[1:]
}

return b.Storage.AddPlugin(plugin)
}
Expand Down
209 changes: 186 additions & 23 deletions brokers/unified/vscode/broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type mocks struct {
randMock *cmock.Random
}

func initMocks() *mocks {
func initMocks(useLocalhost bool) *mocks {
cb := &cmock.Broker{}
u := &fmock.IoUtil{}
randMock := &cmock.Random{}
Expand All @@ -68,12 +68,13 @@ func initMocks() *mocks {
Storage: storage.New(),
client: test.NewTestHTTPClient(okMarketplaceResponse),
rand: randMock,
localhostSidecar: useLocalhost,
},
}
}

func TestStart(t *testing.T) {
m := initMocks()
m := initMocks(false)

m.cb.On("PubStarted").Once()
m.cb.On("PrintDebug", mock.AnythingOfType("string"))
Expand All @@ -88,7 +89,7 @@ func TestStart(t *testing.T) {
}

func TestProcessBrokenPluginUrl(t *testing.T) {
m := initMocks()
m := initMocks(false)
meta := model.PluginMeta{
ID: pluginID,
Version: pluginVersion,
Expand Down Expand Up @@ -124,11 +125,12 @@ func TestProcessBrokenPluginUrl(t *testing.T) {

func TestBroker_processPlugin(t *testing.T) {
cases := []struct {
name string
meta model.PluginMeta
err string
want []model.ChePlugin
unzipFunc UnzipFunc
name string
meta model.PluginMeta
err string
want []model.ChePlugin
unzipFunc UnzipFunc
useLocalhost bool
}{
{
name: "Return error when extensions field is empty and there is no containers",
Expand Down Expand Up @@ -211,7 +213,7 @@ func TestBroker_processPlugin(t *testing.T) {
want: expectedNoPlugin(),
},
{
name: "Successful brokering of remote plugin when extension points to .theia archive",
name: "Successful brokering of remote plugin when extension points to .theia archive, using a generated host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Expand All @@ -230,7 +232,34 @@ func TestBroker_processPlugin(t *testing.T) {
},
},
unzipFunc: createUnzipTheiaArchiveFuncStub(generatePackageJSON("peppers.com", "cool-extension")),
useLocalhost: false,
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
false,
generateTheiaEnvVar("peppers_com_cool_extension")),
},
{
name: "Successful brokering of remote plugin when extension points to .theia archive, using localhost as the host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Version: pluginVersion,
Publisher: pluginPublisher,
Name: pluginName,
Spec: model.PluginMetaSpec{
Extensions: []string{
"https://red-hot-chilli.peppers/plugin.theia",
},
Containers: []model.Container{
{
Image: image,
},
},
},
},
unzipFunc: createUnzipTheiaArchiveFuncStub(generatePackageJSON("peppers.com", "cool-extension")),
useLocalhost: true,
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
true,
generateTheiaEnvVar("peppers_com_cool_extension")),
},
{
Expand Down Expand Up @@ -288,7 +317,7 @@ func TestBroker_processPlugin(t *testing.T) {
want: expectedNoPlugin(),
},
{
name: "Successful brokering of remote plugin with extensions field with several extensions",
name: "Successful brokering of remote plugin with extensions field with several extensions, using a generated host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Expand All @@ -306,12 +335,39 @@ func TestBroker_processPlugin(t *testing.T) {
},
},
},
useLocalhost: false,
unzipFunc: createUnzipFuncStub(generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools")),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
false,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools")),
},
{
name: "Successful brokering of remote plugin with extensions field with several extensions",
name: "Successful brokering of remote plugin with extensions field with several extensions, using localhost as the host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Version: pluginVersion,
Publisher: pluginPublisher,
Name: pluginName,
Spec: model.PluginMetaSpec{
Extensions: []string{
"vscode:extension/ms-kubernetes-tools.vscode-kubernetes-tools",
},
Containers: []model.Container{
{
Image: image,
},
},
},
},
useLocalhost: true,
unzipFunc: createUnzipFuncStub(generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools")),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
true,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools")),
},
{
name: "Successful brokering of remote plugin with extensions field with several extensions, using a generated the host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Expand All @@ -331,17 +387,83 @@ func TestBroker_processPlugin(t *testing.T) {
},
},
},
useLocalhost: false,
unzipFunc: createUnzipFuncStub(
generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools"),
generatePackageJSON("redhat-com", "vscode-jdt-ls"),
generatePackageJSON("redhat-com", "vscode-maven")),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
false,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools"),
generateTheiaEnvVar("redhat_com_vscode_jdt_ls"),
generateTheiaEnvVar("redhat_com_vscode_maven")),
},
{
name: "Successful brokering of remote plugin with extensions field with mixed extensions and archives URLs",
name: "Successful brokering of remote plugin with extensions field with several extensions, using localhost as the host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Version: pluginVersion,
Publisher: pluginPublisher,
Name: pluginName,
Spec: model.PluginMetaSpec{
Extensions: []string{
"vscode:extension/ms-kubernetes-tools.vscode-kubernetes-tools",
"vscode:extension/redhat-com.vscode-jdt-ls",
"vscode:extension/redhat-com.vscode-maven",
},
Containers: []model.Container{
{
Image: image,
},
},
},
},
useLocalhost: true,
unzipFunc: createUnzipFuncStub(
generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools"),
generatePackageJSON("redhat-com", "vscode-jdt-ls"),
generatePackageJSON("redhat-com", "vscode-maven")),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
true,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools"),
generateTheiaEnvVar("redhat_com_vscode_jdt_ls"),
generateTheiaEnvVar("redhat_com_vscode_maven")),
},
{
name: "Successful brokering of remote plugin with extensions field with mixed extensions and archives URLs, using a generated host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Version: pluginVersion,
Publisher: pluginPublisher,
Name: pluginName,
Spec: model.PluginMetaSpec{
Containers: []model.Container{
{
Image: image,
},
},
Extensions: []string{
"vscode:extension/ms-kubernetes-tools.vscode-kubernetes-tools",
vsixURL,
"vscode:extension/redhat-com.vscode-maven",
},
},
},
useLocalhost: false,
unzipFunc: createUnzipFuncStub(
generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools"),
generatePackageJSON("redhat-com", "vscode-jdt-ls"),
generatePackageJSON("redhat-com", "vscode-maven")),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
false,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools"),
generateTheiaEnvVar("redhat_com_vscode_jdt_ls"),
generateTheiaEnvVar("redhat_com_vscode_maven")),
},
{
name: "Successful brokering of remote plugin with extensions field with mixed extensions and archives URLs, using localhost as the host name",
meta: model.PluginMeta{
Type: vscodePluginType,
ID: pluginID,
Expand All @@ -361,17 +483,51 @@ func TestBroker_processPlugin(t *testing.T) {
},
},
},
useLocalhost: true,
unzipFunc: createUnzipFuncStub(
generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools"),
generatePackageJSON("redhat-com", "vscode-jdt-ls"),
generatePackageJSON("redhat-com", "vscode-maven")),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
true,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools"),
generateTheiaEnvVar("redhat_com_vscode_jdt_ls"),
generateTheiaEnvVar("redhat_com_vscode_maven")),
},
{
name: "Successful brokering of remote plugin with extensions field with mixed extensions and archives URLs when plugin type is Theia",
name: "Successful brokering of remote plugin with extensions field with mixed extensions and archives URLs when plugin type is Theia, using a generated host name",
meta: model.PluginMeta{
Type: theiaPluginType,
ID: pluginID,
Version: pluginVersion,
Publisher: pluginPublisher,
Name: pluginName,
Spec: model.PluginMetaSpec{
Containers: []model.Container{
{
Image: image,
},
},
Extensions: []string{
"vscode:extension/ms-kubernetes-tools.vscode-kubernetes-tools",
vsixURL,
"https://red-hot-chilli.peppers/plugin.theia",
},
},
},
useLocalhost: false,
unzipFunc: createUnzipFuncStub(
generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools"),
generatePackageJSON("redhat-com", "vscode-jdt-ls"),
generatePackageJSON("peppers.com", "cool-extension"), ),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
false,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools"),
generateTheiaEnvVar("redhat_com_vscode_jdt_ls"),
generateTheiaEnvVar("peppers_com_cool_extension")),
},
{
name: "Successful brokering of remote plugin with extensions field with mixed extensions and archives URLs when plugin type is Theia, using localhost as the host name",
meta: model.PluginMeta{
Type: theiaPluginType,
ID: pluginID,
Expand All @@ -391,19 +547,21 @@ func TestBroker_processPlugin(t *testing.T) {
},
},
},
useLocalhost: true,
unzipFunc: createUnzipFuncStub(
generatePackageJSON("ms-kubernetes-tools", "vscode-kubernetes-tools"),
generatePackageJSON("redhat-com", "vscode-jdt-ls"),
generatePackageJSON("peppers.com", "cool-extension"), ),
want: expectedPluginsWithSingleRemotePluginWithSeveralExtensions(
true,
generateTheiaEnvVar("ms_kubernetes_tools_vscode_kubernetes_tools"),
generateTheiaEnvVar("redhat_com_vscode_jdt_ls"),
generateTheiaEnvVar("peppers_com_cool_extension")),
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
m := initMocks()
m := initMocks(tt.useLocalhost)
workDir := tests.CreateTestWorkDir()
defer tests.RemoveAll(workDir)
setUpSuccessfulCase(workDir, tt.meta, m, tt.unzipFunc)
Expand Down Expand Up @@ -432,19 +590,13 @@ func generateTheiaEnvVar(prettyID string) string {
return "THEIA_PLUGIN_REMOTE_ENDPOINT_" + prettyID
}

func expectedPluginsWithSingleRemotePluginWithSeveralExtensions(pluginTheiaEndpointVars ...string) []model.ChePlugin {
func expectedPluginsWithSingleRemotePluginWithSeveralExtensions(usedLocalhost bool, pluginTheiaEndpointVars ...string) []model.ChePlugin {
expectedPlugin := model.ChePlugin{
ID: pluginID,
Version: pluginVersion,
Publisher: pluginPublisher,
Name: pluginName,
Endpoints: []model.Endpoint{
{
Name: "randomString1234567890",
Public: false,
TargetPort: 4242,
},
},
Endpoints: []model.Endpoint{},
Containers: []model.Container{
{
Image: image,
Expand All @@ -469,10 +621,21 @@ func expectedPluginsWithSingleRemotePluginWithSeveralExtensions(pluginTheiaEndpo
},
},
}
if ! usedLocalhost {
expectedPlugin.Endpoints = append(expectedPlugin.Endpoints, model.Endpoint{
Name: "randomString1234567890",
Public: false,
TargetPort: 4242,
})
}
for _, envVarName := range pluginTheiaEndpointVars {
hostName := "randomString1234567890"
if (usedLocalhost) {
hostName = "localhost"
}
expectedPlugin.WorkspaceEnv = append(expectedPlugin.WorkspaceEnv, model.EnvVar{
Name: envVarName,
Value: "ws://randomString1234567890:4242",
Value: "ws://" + hostName + ":4242",
})
}

Expand Down
11 changes: 10 additions & 1 deletion cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ var (
// UseLocalhostInPluginUrls configures the broker to use the `localhost` name
// instead of the Kubernetes service name to build Theia or VSCode plugin
// endpoint URL
UseLocalhostInPluginUrls bool
// True by default since until now all remote VS Code or Theia plugin containers
// are started on the same POD as the Theia IDE container
UseLocalhostInPluginUrls = true

// OnlyApplyMetadataActions configures the broker to only apply metadata-related
// steps, without copying any file into the `plugins` directory
Expand Down Expand Up @@ -115,6 +117,13 @@ func init() {
"Output events that are usually sent Che master instead of regular logs to imitate what a user can see."+
"`false` by default. Needed for testing and debugging purposes",
)
flag.BoolVar(
&UseLocalhostInPluginUrls,
"use-localhost-in-plugin-urls",
true,
"This configures the broker to use the `localhost` name instead of the Kubernetes service name to build Theia or VSCode plugin endpoint URL."+
"`true` by default since until now all remote VS Code or Theia plugin containers are started on the same POD as the Theia IDE container",
)
flag.StringVar(
&RegistryAddress,
"registry-address",
Expand Down