diff --git a/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliEnvTest.java b/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliEnvTest.java new file mode 100644 index 000000000..2f10ba803 --- /dev/null +++ b/src/it/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCliEnvTest.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2024 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package org.jboss.tools.intellij.openshift.utils.helm; + + +import org.jboss.tools.intellij.openshift.utils.helm.HelmCli.HelmEnv; + +import static org.fest.assertions.Assertions.assertThat; + +public class HelmCliEnvTest extends HelmCliTest { + + public void testEnv_should_return_current_namespace() throws Exception { + // given + // when + HelmEnv env = helm.env(); + // then + assertThat(env.get(HelmEnv.HELM_NAMESPACE)).isNotEmpty(); + } +} diff --git a/src/main/java/org/jboss/tools/intellij/openshift/actions/helm/OpenHelmChartsAction.java b/src/main/java/org/jboss/tools/intellij/openshift/actions/helm/OpenHelmChartsAction.java index 3178b2f2b..ca39235a1 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/actions/helm/OpenHelmChartsAction.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/actions/helm/OpenHelmChartsAction.java @@ -19,6 +19,7 @@ import org.jboss.tools.intellij.openshift.tree.application.ParentableNode; import org.jboss.tools.intellij.openshift.ui.helm.ChartsDialog; import org.jboss.tools.intellij.openshift.utils.helm.Helm; +import org.jboss.tools.intellij.openshift.utils.odo.Odo; import org.jetbrains.annotations.NotNull; public class OpenHelmChartsAction extends HelmAction { @@ -26,8 +27,15 @@ public class OpenHelmChartsAction extends HelmAction { @Override public void actionPerformedOnSelectedObject(AnActionEvent anActionEvent, Object selected, @NotNull Helm helm) { Project project = getEventProject(anActionEvent); + if (selected == null) { + return; + } ApplicationsRootNode rootNode = ((ParentableNode) selected).getRoot(); - ChartsDialog dialog = new ChartsDialog(rootNode, helm, project); + Odo odo = rootNode.getOdo().getNow(null); + if (odo == null) { + return; + } + ChartsDialog dialog = new ChartsDialog(rootNode, helm, odo, project); sendTelemetryResults(TelemetryService.TelemetryResult.SUCCESS); dialog.show(); } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartPanels.java b/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartPanels.java index 886cc0991..e3a510eeb 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartPanels.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartPanels.java @@ -15,6 +15,7 @@ import com.intellij.openapi.util.Disposer; import org.jboss.tools.intellij.openshift.tree.application.ApplicationsRootNode; import org.jboss.tools.intellij.openshift.utils.helm.Helm; +import org.jboss.tools.intellij.openshift.utils.odo.Odo; import javax.swing.JComponent; import java.awt.Component; @@ -27,12 +28,14 @@ public class ChartPanels extends MultiPanel { private final ApplicationsRootNode rootNode; private final Helm helm; + private final Odo odo; private ChartVersions chart; private final Disposable disposable = Disposer.newDisposable(); - public ChartPanels(ApplicationsRootNode rootNode, Disposable parentDisposable, Helm helm) { + public ChartPanels(ApplicationsRootNode rootNode, Disposable parentDisposable, Helm helm, Odo odo) { this.rootNode = rootNode; this.helm = helm; + this.odo = odo; Disposer.register(parentDisposable, disposable); } @@ -41,7 +44,7 @@ protected JComponent create(Integer key) { if (key == DETAILS_PANEL) { return new DetailsPanel(chart, disposable, this); } else if (key == INSTALL_PANEL) { - return new InstallPanel(chart, rootNode, disposable, helm); + return new InstallPanel(chart, rootNode, disposable, helm, odo); } else { return null; } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartsDialog.java b/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartsDialog.java index c675a79de..69fa8ac33 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartsDialog.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/ChartsDialog.java @@ -36,6 +36,7 @@ import org.jboss.tools.intellij.openshift.ui.TableRowFilterFactory; import org.jboss.tools.intellij.openshift.utils.helm.Chart; import org.jboss.tools.intellij.openshift.utils.helm.Helm; +import org.jboss.tools.intellij.openshift.utils.odo.Odo; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,16 +74,18 @@ public class ChartsDialog extends DialogWrapper { private final ApplicationsRootNode rootNode; private final Helm helm; + private final Odo odo; private JBLabel title; private ChartsTableModel chartsTableModel; private JBTable chartsTable; private StatusIcon statusIcon; - public ChartsDialog(ApplicationsRootNode rootNode, Helm helm, Project project) { + public ChartsDialog(ApplicationsRootNode rootNode, Helm helm, Odo odo, Project project) { super(project, null, false, IdeModalityType.MODELESS, false); this.rootNode = rootNode; this.helm = helm; + this.odo = odo; init(); } @@ -99,11 +102,7 @@ protected void init() { setupTable(chartsTable, chartsTableModel, statusIcon) .thenCompose((Void) -> addDefaultRepo(helm)) - .whenComplete((Void, throwable) -> { - if (throwable == null) { - load(chartsTable, chartsTableModel, statusIcon, helm); - } - }); + .thenCompose((Void) -> load(chartsTable, chartsTableModel, statusIcon, helm)); } private static void setBorders(JRootPane rootPane) { @@ -114,9 +113,10 @@ private static void setBorders(JRootPane rootPane) { private void registerShortcuts(JRootPane rootPane) { AnAction escape = ActionManager.getInstance().getAction("EditorEscape"); DumbAwareAction.create(e -> closeImmediately()) - .registerCustomShortcutSet(escape == null ? - CommonShortcuts.ESCAPE - : escape.getShortcutSet(), rootPane, myDisposable); + .registerCustomShortcutSet( + escape == null ? CommonShortcuts.ESCAPE : escape.getShortcutSet(), + rootPane, + myDisposable); } @Override @@ -161,7 +161,7 @@ private void registerShortcuts(JRootPane rootPane) { .usingInput(filterTextArea.getDocument()); splitter.setFirstComponent(tableScrolledPane); - ChartPanels chartPanels = new ChartPanels(rootNode, getDisposable(), helm); + ChartPanels chartPanels = new ChartPanels(rootNode, getDisposable(), helm, odo); chartPanels.select(ChartPanels.DETAILS_PANEL,true); chartsTable.getSelectionModel().addListSelectionListener( onTableItemSelected(chartPanels, chartsTable, chartsTableModel)); @@ -233,7 +233,7 @@ private CompletableFuture load( LOGGER.warn("Could not load all helm charts.", e); return Collections.emptyList(); } - }, SwingUtils.EXECUTOR_BACKGROUND) + }, EXECUTOR_BACKGROUND) .thenAcceptAsync((charts) -> { List chartVersions = toChartVersions(charts); tableModel.setCharts(chartVersions); diff --git a/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/InstallPanel.java b/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/InstallPanel.java index 252267f21..1d14e05c7 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/InstallPanel.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/ui/helm/InstallPanel.java @@ -33,6 +33,8 @@ import org.jboss.tools.intellij.openshift.ui.StatusIcon; import org.jboss.tools.intellij.openshift.ui.SwingUtils; import org.jboss.tools.intellij.openshift.utils.helm.Helm; +import org.jboss.tools.intellij.openshift.utils.helm.HelmCli; +import org.jboss.tools.intellij.openshift.utils.odo.Odo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,6 +52,7 @@ import java.io.IOException; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.function.Supplier; import java.util.regex.Pattern; @@ -62,6 +65,7 @@ class InstallPanel extends JBPanel implements ChartPanel, Disposab private final ApplicationsRootNode rootNode; private final Helm helm; + private final Odo odo; private final Disposable disposable = Disposer.newDisposable(); private final TelemetryMessageBuilder.ActionMessage telemetry = @@ -74,6 +78,7 @@ class InstallPanel extends JBPanel implements ChartPanel, Disposab private JLabel icon; private JTextField releaseNameText; + private JBLabel currentProject; private JLabel chartNameLabel; private ComboBox versionsCombo; private JBTextField parameters; @@ -83,7 +88,7 @@ class InstallPanel extends JBPanel implements ChartPanel, Disposab private JPanel installResultPanel; private JButton installButton; - InstallPanel(ChartVersions chart, ApplicationsRootNode rootNode, Disposable parentDisposable, Helm helm) { + InstallPanel(ChartVersions chart, ApplicationsRootNode rootNode, Disposable parentDisposable, Helm helm, Odo odo) { super(new MigLayout( "flowx, fillx, hidemode 3", "[50:50:50] [left, 100:100:100] [left] [left, fill] [right]"), @@ -91,6 +96,7 @@ class InstallPanel extends JBPanel implements ChartPanel, Disposab this.chart = chart; this.rootNode = rootNode; this.helm = helm; + this.odo = odo; initComponents(); Disposer.register(parentDisposable, disposable); } @@ -120,6 +126,11 @@ private void initComponents() { releaseNameText.addKeyListener(onKeyPressed(installButton)); add(releaseNameText, "spanx 2, pushx, growx, wrap"); + add(new JBLabel("Active " + (odo.isAuthorized()? "project:" : "namespace")),"skip"); + this.currentProject = new JBLabel(); + // value set in validation + add(currentProject, "pushx, wrap"); + add(new JBLabel("Version:"), "skip"); this.versionsCombo = new ComboBox<>(new String[]{}); versionsCombo.addItemListener(onVersionSelected()); @@ -144,6 +155,18 @@ private void initComponents() { setChart(chart); } + private CompletableFuture loadCurrentNamespace() { + return CompletableFuture.supplyAsync(() -> { + try { + HelmCli.HelmEnv env = helm.env(); + return env.get(HelmCli.HelmEnv.HELM_NAMESPACE); + } catch (IOException e) { + throw new CompletionException(e); + } + }, + EXECUTOR_BACKGROUND); + } + private ItemListener onVersionSelected() { return e -> { if (e.getStateChange() == ItemEvent.SELECTED) { @@ -309,6 +332,12 @@ private void updateComponents(PanelState panelState) { } } + private void updateCurrentProjectLabel() { + loadCurrentNamespace() + .thenAcceptAsync(currentProject -> InstallPanel.this.currentProject.setText(currentProject) + , EXECUTOR_UI); + } + @Override public void dispose() { disposable.dispose(); @@ -332,6 +361,7 @@ public ValidationInfo get() { } ValidationInfo validation = validate(field.getText()); enableInstallButton(validation); + updateCurrentProjectLabel(); // update in validation to have most frequent polling return validation; } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/Helm.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/Helm.java index cdb34aabb..e07655da9 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/Helm.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/Helm.java @@ -26,4 +26,6 @@ public interface Helm { String install(String name, String chart, String version, String parameters) throws IOException; String uninstall(String... names) throws IOException; + + HelmCli.HelmEnv env() throws IOException; } diff --git a/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCli.java b/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCli.java index c9a11b88c..2f0e3ad79 100644 --- a/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCli.java +++ b/src/main/java/org/jboss/tools/intellij/openshift/utils/helm/HelmCli.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.redhat.devtools.intellij.telemetry.core.service.TelemetryMessageBuilder.ActionMessage; import static org.jboss.tools.intellij.openshift.Constants.HOME_FOLDER; @@ -130,9 +131,67 @@ public String uninstall(String... names) throws IOException { arguments); } + @Override + public HelmEnv env() throws IOException { + String result = execute(command, Collections.emptyMap(), "env"); + /* + * HELM_NAMESPACE="default" + * HELM_KUBECONTEXT="" + */ + Map env = Stream.of(result.split("\n")) + .collect(Collectors.toMap( + (String line) -> line.split("=", 2)[0], + (String line) -> { + String[] keyValue = line.split("=", 2); + if (keyValue.length > 2) { + return ""; + } else { + return keyValue[1].replaceAll("\"", ""); + } + } + )); + return new HelmEnv(env); + } + private static String execute(String command, Map envs, String... args) throws IOException { File workingDirectory = new File(HOME_FOLDER); ExecHelper.ExecResult output = ExecHelper.executeWithResult(command, true, workingDirectory, envs, args); return output.getStdOut(); } + + public static class HelmEnv { + + public static final String HELM_BIN = "HELM_BIN"; + public static final String HELM_BURST_LIMIT = "HELM_BURST_LIMIT"; + public static final String HELM_CACHE_HOME = "HELM_CACHE_HOME"; + public static final String HELM_CONFIG_HOME = "HELM_CONFIG_HOME"; + public static final String HELM_DATA_HOME = "HELM_DATA_HOME"; + public static final String HELM_DEBUG = "HELM_DEBUG"; + public static final String HELM_KUBEAPISERVER = "HELM_KUBEAPISERVER"; + public static final String HELM_KUBEASGROUPS = "HELM_KUBEASGROUPS"; + public static final String HELM_KUBEASUSER = "HELM_KUBEASUSER"; + public static final String HELM_KUBECAFILE = "HELM_KUBECAFILE"; + public static final String HELM_KUBECONTEXT = "HELM_KUBECONTEXT"; + public static final String HELM_KUBEINSECURE_SKIP_TLS_VERIFY = "HELM_KUBEINSECURE_SKIP_TLS_VERIFY"; + public static final String HELM_KUBETLS_SERVER_NAME = "HELM_KUBETLS_SERVER_NAME"; + public static final String HELM_KUBETOKEN = "HELM_KUBETOKEN"; + public static final String HELM_MAX_HISTORY = "HELM_MAX_HISTORY"; + public static final String HELM_NAMESPACE = "HELM_NAMESPACE"; + public static final String HELM_PLUGINS = "HELM_PLUGINS"; + public static final String HELM_QPS = "HELM_QPS"; + public static final String HELM_REGISTRY_CONFIG = "HELM_REGISTRY_CONFIG"; + public static final String HELM_REPOSITORY_CACHE = "HELM_REPOSITORY_CACHE"; + public static final String HELM_REPOSITORY_CONFIG = "HELM_REPOSITORY_CONFIG"; + + private final Map env; + + public HelmEnv(Map env) { + this.env = env; + } + + public String get(final String key) { + return env.get(key); + } + } + } \ No newline at end of file