Skip to content

Commit

Permalink
feat: list helm repositories (#672)
Browse files Browse the repository at this point in the history
Signed-off-by: Andre Dietisheim <[email protected]>
  • Loading branch information
adietish committed Mar 12, 2024
1 parent cfd17d1 commit 2029275
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,19 @@ public Object getApplicationsRoot() {

@NotNull
@Override
public Object @NotNull [] getChildElements(@NotNull Object element) {
public Object @NotNull [] getChildElements(@NotNull Object element) {
try {
if (element == this) {
return new Object[]{root, registries};
} else if (element instanceof ApplicationsRootNode) {
return getCurrentNamespace((ApplicationsRootNode) element);
return new Object[] {
getCurrentNamespace((ApplicationsRootNode) element),
new HelmRepositoriesNode((ApplicationsRootNode) element)
};
} else if (element instanceof NamespaceNode) {
return createNamespaceChildren((NamespaceNode) element);
} else if (element instanceof HelmRepositoriesNode) {
return createHelmRepositoriesChildren((HelmRepositoriesNode) element);
} else if (element instanceof ComponentNode) {
return createComponentChildren((ComponentNode) element);
} else if (element instanceof DevfileRegistriesNode) {
Expand Down Expand Up @@ -136,8 +141,9 @@ private Object[] createNamespaceChildren(@NotNull NamespaceNode namespaceNode) {
return nodes.toArray();
}

private Object[] getCurrentNamespace(ApplicationsRootNode element) {
List<Object> namespaces = new ArrayList<>();
@NotNull
private Object getCurrentNamespace(ApplicationsRootNode element) {
Object node;
try {
Odo odo = root.getOdo().getNow(null);
if (odo == null) {
Expand All @@ -146,20 +152,38 @@ private Object[] getCurrentNamespace(ApplicationsRootNode element) {
boolean isAuthorized = odo.isAuthorized();
element.setLogged(isAuthorized);
if (!isAuthorized) {
namespaces.add(new MessageNode<>(root, root, LOGIN));
node = new MessageNode<>(root, root, LOGIN);
} else {
String namespace = odo.getCurrentNamespace();
if (namespace != null) {
namespaces.add(new NamespaceNode(element, namespace));
node = new NamespaceNode(element, namespace);
} else {
namespaces.add(new CreateNamespaceLinkNode(element));
node = new CreateNamespaceLinkNode(element);
}
}
} catch (Exception e) {
namespaces.add(createErrorNode(element, e));
node = createErrorNode(element, e);
element.setLogged(false);
}
return namespaces.toArray();
return node;
}

private Object[] createHelmRepositoriesChildren(HelmRepositoriesNode parent) {
Helm helm = root.getHelm(true).getNow(null);
if (helm == null) {
return new Object[] { new MessageNode<>(root, parent, "Could not list repositories: Helm binary missing.") };
}
try {
var repositories = helm.listRepos();
if (repositories == null) {
return new Object[] { new MessageNode<>(root, parent, "Could not list repositories: no repositories defined.") };
}
return repositories.stream()
.map(repository -> new HelmRepositoryNode(root, parent, repository))
.toArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private MessageNode<?> createErrorNode(ParentableNode<?> parent, Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.redhat.devtools.intellij.common.tree.LabelAndIconDescriptor;
import org.jboss.tools.intellij.openshift.ui.SwingUtils;
import org.jboss.tools.intellij.openshift.ui.helm.ChartIcons;
import org.jboss.tools.intellij.openshift.utils.odo.Binding;
import org.jboss.tools.intellij.openshift.utils.odo.Component;
Expand All @@ -35,8 +36,11 @@ public class DescriptorFactory {
private static final Icon COMPONENT_TYPE_ICON = IconLoader.findIcon("/images/component-type-light.png", ApplicationsTreeStructure.class);
private static final Icon STARTER_ICON = IconLoader.findIcon("/images/start-project-light.png", ApplicationsTreeStructure.class);
private static final Icon REGISTRY_ICON = IconLoader.findIcon("/images/registry.svg", ApplicationsTreeStructure.class);
private static final Icon HELM_REPOSITORY_ICON = IconLoader.findIcon("/images/helm/repo.svg", ApplicationsTreeStructure.class);

public static @NotNull NodeDescriptor<?> create(@NotNull Object element, @Nullable NodeDescriptor parentDescriptor, @NotNull ApplicationsTreeStructure structure, @NotNull Project project) {
private static final int ICON_WIDTH = 15;

public static @NotNull NodeDescriptor<?> create(@NotNull Object element, @Nullable NodeDescriptor<?> parentDescriptor, @NotNull ApplicationsTreeStructure structure, @NotNull Project project) {
if (element == structure) {
return new LabelAndIconDescriptor<>(
project,
Expand Down Expand Up @@ -157,7 +161,29 @@ public class DescriptorFactory {
releaseNode,
releaseNode::getName,
() -> "Helm Release",
() -> ChartIcons.getIcon15x15(releaseNode.getRelease()),
() -> SwingUtils.scaleIcon(ICON_WIDTH, ChartIcons.getIcon(releaseNode.getRelease())),
parentDescriptor);
} else if (element instanceof HelmRepositoriesNode) {
HelmRepositoriesNode helmRepositoriesNode = (HelmRepositoriesNode) element;
return new ApplicationsTreeStructure.ProcessableDescriptor<>(
project,
helmRepositoriesNode,
helmRepositoriesNode::getName,
() -> "Repositories",
() -> SwingUtils.scaleIcon(ICON_WIDTH, ChartIcons.getHelmIcon()),
parentDescriptor);
} else if (element instanceof HelmRepositoryNode) {
HelmRepositoryNode helmRepositoryNode = (HelmRepositoryNode) element;
return new ApplicationsTreeStructure.ProcessableDescriptor<>(
project,
helmRepositoryNode,
helmRepositoryNode::getName,
() -> {
var repository = helmRepositoryNode.getRepository();
return repository != null ?
repository.getUrl() : "";
},
() -> HELM_REPOSITORY_ICON,
parentDescriptor);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*******************************************************************************
* 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.tree.application;

public class HelmRepositoriesNode extends BaseNode<ApplicationsRootNode> {
public HelmRepositoriesNode(ApplicationsRootNode parent) {
super(parent, parent, "Helm");
}
}
Original file line number Diff line number Diff line change
@@ -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.tree.application;

import org.jboss.tools.intellij.openshift.utils.helm.Repository;

public class HelmRepositoryNode extends BaseNode<HelmRepositoriesNode> {

private final Repository repository;

public HelmRepositoryNode(ApplicationsRootNode root, HelmRepositoriesNode parent, Repository repository) {
super(root, parent, repository.getName());
this.repository = repository;
}

public Repository getRepository() {
return repository;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.wm.impl.IdeGlassPaneEx;
import com.intellij.ui.JBColor;
import com.intellij.ui.SizedIcon;
import com.intellij.ui.WindowMoveListener;
import com.intellij.ui.WindowResizeListener;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.ui.table.JBTable;
import com.intellij.util.containers.JBIterable;
import com.intellij.util.ui.JBFont;
Expand All @@ -26,6 +28,7 @@

import javax.swing.AbstractButton;
import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
Expand Down Expand Up @@ -149,4 +152,10 @@ public static Point locationOrMouseLocation(Point location) {
return location;
}

public static Icon scaleIcon(int width, Icon icon) {
float scale = (float) width / icon.getIconWidth();
SizedIcon scaled = JBUIScale.scaleIcon(new SizedIcon(icon, icon.getIconWidth(), icon.getIconHeight()));
return scaled.scale(scale);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
package org.jboss.tools.intellij.openshift.ui.helm;

import com.intellij.ui.IconManager;
import com.intellij.ui.SizedIcon;
import com.intellij.ui.scale.JBUIScale;
import org.jboss.tools.intellij.openshift.utils.helm.ChartRelease;

import javax.swing.Icon;
Expand All @@ -26,28 +24,25 @@ public class ChartIcons {
private static final Path BASE_PATH = Paths.get("images", "helm");
private static final String HELM_ICON = "helm.png";

public static javax.swing.Icon getIcon(ChartVersions chart) {
return getIcon(chart.getName() + chart.getDescription());
public static Icon getHelmIcon() {
return IconManager.getInstance().getIcon(BASE_PATH.resolve(HELM_ICON).toString(), ChartIcons.class);
}

public static javax.swing.Icon getIcon(ChartRelease chart) {
return getIcon(chart.getChart());
public static Icon getIcon(ChartVersions chart) {
return getIcon(chart.getName() + chart.getDescription());
}

public static javax.swing.Icon getIcon15x15(ChartRelease chart) {
Icon icon = getIcon(chart);
float scale = 15f / icon.getIconWidth();
SizedIcon sized = JBUIScale.scaleIcon(new SizedIcon(icon, icon.getIconHeight(), icon.getIconHeight()));
return sized.scale(scale);
public static Icon getIcon(ChartRelease chart) {
return getIcon(chart.getChart());
}

private static javax.swing.Icon getIcon(String name) {
private static Icon getIcon(String name) {
Optional<IconExpression> found = Stream.of(IconExpression.values())
.filter((IconExpression available) -> available.isMatching(name))
.findFirst();
return found
.map(iconExpression -> IconManager.getInstance().getIcon(iconExpression.filename, ChartIcons.class))
.orElseGet(() -> IconManager.getInstance().getIcon(BASE_PATH.resolve(HELM_ICON).toString(), ChartIcons.class));
.orElseGet(ChartIcons::getHelmIcon);
}

private enum IconExpression {
Expand Down Expand Up @@ -88,5 +83,4 @@ public boolean isMatching(String chartText) {
return chartText.toLowerCase().contains(substring.toLowerCase());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public interface Helm {

String addRepo(String name, String url) throws IOException;

List<Repository> listRepos() throws IOException;

List<Chart> search() throws IOException;

List<Chart> search(String regex) throws IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ public String addRepo(String name, String url) throws IOException {
}
}

@Override
public List<Repository> listRepos() throws IOException {
ActionMessage telemetry = TelemetryService.instance().getBuilder().action(
TelemetryService.NAME_PREFIX_MISC + "helm-list repo");
try {
LOGGER.info("Listing repos.");
String repos = execute(command, Collections.emptyMap(), "repo", "list", "-o=json");
asyncSend(telemetry.success());
return Serialization.json().readValue(repos, new TypeReference<>() {});
} catch (IOException e) {
asyncSend(telemetry.error(e));
throw e;
}
}

@Override
public List<Chart> search() throws IOException {
ActionMessage telemetry = TelemetryService.instance().getBuilder().action(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*******************************************************************************
* 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 com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Repository {

private String name;
private String url;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Binary file removed src/main/resources/images/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions src/main/resources/images/helm/repo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2029275

Please sign in to comment.