Skip to content

Commit

Permalink
Charts version can be read and chosen on creation (#155)
Browse files Browse the repository at this point in the history
With this PR the user can now read all charts version via new endpoints.
These charts are now fetched in catalog wrapper as well as the last one.
The packageVersion in creation request is now passed to helm.
Also creating a service which already exists upgrade it instead of
failing. This allows user to upgrade there service version.
Plus service exposes more helm data.
  • Loading branch information
fcomte authored Sep 15, 2022
1 parent d14a01c commit d2f7ba3
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import io.github.inseefrlab.helmwrapper.model.HelmInstaller;
import io.github.inseefrlab.helmwrapper.model.HelmLs;
import io.github.inseefrlab.helmwrapper.utils.Command;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zeroturnaround.exec.InvalidExitValueException;
Expand All @@ -28,10 +30,10 @@ public class HelmInstallService {
public HelmInstallService() {

}
public HelmInstaller installChart(HelmConfiguration configuration,String chart, String namespace, String name, boolean dryRun, File values,
Map<String, String> env)
public HelmInstaller installChart(HelmConfiguration configuration,String chart, String namespace, String name, String version,
boolean dryRun, File values, Map<String, String> env)
throws InvalidExitValueException, IOException, InterruptedException, TimeoutException {
String command = "helm install ";
String command = "helm upgrade --install ";
if (name != null) {
command = command.concat(name+ " ");
}
Expand All @@ -40,6 +42,9 @@ public HelmInstaller installChart(HelmConfiguration configuration,String chart,
}
command = command.concat(chart+" ");
command = command.concat("-n "+namespace);
if (StringUtils.isNotBlank(version)) {
command = command.concat(" --version " + version);
}
if (values != null) {
command = command.concat(" -f " + values.getAbsolutePath());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import fr.insee.onyxia.model.catalog.Config.Property;
import fr.insee.onyxia.model.catalog.Config.Property.XForm;
import fr.insee.onyxia.model.catalog.Config.Property.XOnyxia;
import fr.insee.onyxia.model.helm.Chart;
import fr.insee.onyxia.model.catalog.Pkg;
import fr.insee.onyxia.model.region.Region;
import fr.insee.onyxia.model.service.Service;
Expand All @@ -21,11 +22,12 @@
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Tag(name = "Public")
@RequestMapping(value={"/api/public/catalog", "/public/catalog"})
@RequestMapping(value={"/api/public/catalog", "/public/catalog", "/api/public/catalogs", "/public/catalogs"})
@RestController
public class CatalogController {

Expand Down Expand Up @@ -92,6 +94,62 @@ public Pkg getPackage(@PathVariable String catalogId, @PathVariable String packa
return pkg;
}

@Operation(
summary = "Get a helm chart from a specific catalog by version.",
description = "Get a helm chart from a specific catalog by version, with detailed information on the package including: descriptions, sources, and configuration options.",
parameters = {
@Parameter(
required = true,
name = "catalogId",
description = "Unique ID of the enabled catalog for this Onyxia API.",
in = ParameterIn.PATH
),
@Parameter(
required = true,
name = "chartName",
description = "Unique name of the chart from the selected catalog.",
in = ParameterIn.PATH
),
@Parameter(
required = true,
name = "version",
description = "Version of the chart",
in = ParameterIn.PATH
)
}
)
@GetMapping("{catalogId}/charts/{chartName}/versions/{version}")
public Chart getChartByVersion(@PathVariable String catalogId, @PathVariable String chartName, @PathVariable String version) {
Chart chart = catalogService.getChartByVersion(catalogId, chartName, version).orElseThrow(NotFoundException::new);
addCustomOnyxiaProperties(chart);
return chart;
}

@Operation(
summary = "Get all versions of a chart from a specific catalog.",
description = "Get all versions of a chart from a specific catalog, with detailed information on the package including: descriptions, sources, and configuration options.",
parameters = {
@Parameter(
required = true,
name = "catalogId",
description = "Unique ID of the enabled catalog for this Onyxia API.",
in = ParameterIn.PATH
),
@Parameter(
required = true,
name = "chartName",
description = "Unique name of the chart from the selected catalog.",
in = ParameterIn.PATH
)
}
)
@GetMapping("{catalogId}/charts/{chartName}")
public List<Chart> getCharts(@PathVariable String catalogId, @PathVariable String chartName) {
List<Chart> charts = catalogService.getCharts(catalogId, chartName).orElseThrow(NotFoundException::new);
charts.stream().forEach(this::addCustomOnyxiaProperties);
return charts;
}

private boolean isCatalogEnabled(Region region, CatalogWrapper catalog) {
if (region == null) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

@Service
public class CatalogLoader {
Expand Down Expand Up @@ -60,13 +61,17 @@ private void updateHelmRepository(CatalogWrapper cw) {
Reader reader = new InputStreamReader(resourceLoader.getResource(cw.getLocation()+"/index.yaml").getInputStream(),
"UTF-8");
Repository repository = mapperHelm.readValue(reader, Repository.class);
repository.getPackages().parallelStream().forEach(pkg -> {
try {
refreshPackage(cw, pkg);
} catch (IOException e) {
e.printStackTrace();
}
repository.getEntries().values().parallelStream().forEach(entry -> {
entry.parallelStream().forEach(pkg -> {
try {
refreshPackage(cw, pkg);
} catch (IOException e) {
e.printStackTrace();
}
});
});
repository.setPackages(repository.getEntries().values().stream().map(charts -> charts.get(0))
.filter(chart -> "application".equalsIgnoreCase(chart.getType())).collect(Collectors.toList()));
cw.setCatalog(repository);
cw.setLastUpdateTime(System.currentTimeMillis());
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package fr.insee.onyxia.api.services;

import java.util.List;
import java.util.Optional;

import fr.insee.onyxia.api.configuration.CatalogWrapper;
import fr.insee.onyxia.api.configuration.Catalogs;
import fr.insee.onyxia.model.catalog.Pkg;
import fr.insee.onyxia.model.helm.Chart;

public interface CatalogService {

Expand All @@ -11,4 +15,8 @@ public interface CatalogService {
public CatalogWrapper getCatalogById(String catalogId);

public Pkg getPackage(String catalogId, String packageName);

public Optional<Chart> getChartByVersion(String catalogId, String chartName, String version);

public Optional<List<Chart>> getCharts(String catalogId, String chartName);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package fr.insee.onyxia.api.services.impl;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import fr.insee.onyxia.api.configuration.CatalogWrapper;
import fr.insee.onyxia.api.configuration.Catalogs;
import fr.insee.onyxia.api.services.CatalogService;
import fr.insee.onyxia.model.catalog.Pkg;
import fr.insee.onyxia.model.helm.Chart;

@Service
public class CatalogServiceImpl implements CatalogService {
Expand All @@ -29,4 +33,18 @@ public Pkg getPackage(String catalogId, String packageName) {
return catalogs.getCatalogById(catalogId).getCatalog().getPackageByName(packageName);
}

@Override
public Optional<List<Chart>> getCharts(String catalogId, String chartName) {
return Optional.ofNullable(catalogs.getCatalogById(catalogId).getCatalog().getEntries().get(chartName));
}

@Override
public Optional<Chart> getChartByVersion(String catalogId, String chartName, String version) {
List<Chart> charts = catalogs.getCatalogById(catalogId).getCatalog().getEntries().get(chartName);
if (charts != null) {
return charts.stream().filter(c -> c.getVersion().equalsIgnoreCase(version)).findAny();
}
else return Optional.empty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public String getInitScript(String scopeName, XGeneratedContext.Scope scope, Pro
File values = File.createTempFile("values", ".yaml");
mapperHelm.writeValue(values, fusion);
String namespaceId = kubernetesService.determineNamespaceAndCreateIfNeeded(region, project, user);
HelmInstaller res = getHelmInstallService().installChart(getHelmConfiguration(region, user), catalogId + "/" + pkg.getName(), namespaceId, requestDTO.getName(), requestDTO.isDryRun(),
HelmInstaller res = getHelmInstallService().installChart(getHelmConfiguration(region, user), catalogId + "/" + pkg.getName(), namespaceId, requestDTO.getName(), requestDTO.getPackageVersion(), requestDTO.isDryRun(),
values, null);
values.delete();
return List.of(res.getManifest());
Expand Down Expand Up @@ -201,7 +201,6 @@ public UninstallService destroyService(Region region, Project project, User user
private Service getHelmApp(Region region, User user, HelmLs release) {
String manifest = getHelmInstallService().getManifest(getHelmConfiguration(region, user), release.getName(), release.getNamespace());
Service service = getServiceFromRelease(region, release, manifest, user);
service.setStatus(findAppStatus(release));
try {
service.setStartedAt(helmDateFormat.parse(release.getUpdated()).getTime());
} catch (ParseException e) {
Expand All @@ -211,6 +210,12 @@ private Service getHelmApp(Region region, User user, HelmLs release) {
service.setName(release.getName());
service.setSubtitle(release.getChart());
service.setType(Service.ServiceType.KUBERNETES);
service.setName(release.getName());
service.setNamespace(release.getNamespace());
service.setRevision(release.getRevision());
service.setStatus(release.getStatus());
service.setUpdated(release.getUpdated());
service.setAppVersion(release.getAppVersion());
try {
String values = getHelmInstallService().getValues(getHelmConfiguration(region, user), release.getName(), release.getNamespace());
JsonNode node = new ObjectMapper().readTree(values);
Expand Down Expand Up @@ -301,17 +306,4 @@ private Service getServiceFromRelease(Region region, HelmLs release, String mani

return service;
}


private Service.ServiceStatus findAppStatus(HelmLs release) {
if (release.getStatus().equals("deployed")) {
return Service.ServiceStatus.RUNNING;
} else if (release.getStatus().equals("pending")) {
return Service.ServiceStatus.DEPLOYING;
} else {
return Service.ServiceStatus.STOPPED;
}
}


}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package fr.insee.onyxia.model.catalog;

import java.util.List;
import java.util.Map;
import fr.insee.onyxia.model.helm.Chart;

public abstract class CatalogWrapper {

private List<Pkg> packages;

private Map<String, List<Chart>> entries;
/**
* @return the packages
*/
Expand All @@ -28,4 +30,19 @@ public Pkg getPackageByName(String name) {
}
return null;
}

/**
* @return the packages
*/
public Map<String, List<Chart>> getEntries() {
return entries;
}

/**
* @param entries the packages to set
*/
public void setEntries(Map<String, List<Chart>> entries) {
this.entries = entries;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public void setAdditionalProperty(String name, Object value) {

@JsonProperty("entries")
public void setEntries(Map<String, List<Chart>> entries) {
super.setEntries(entries);
setPackages(entries.values().stream().map(charts -> charts.get(0)).filter(chart -> "application".equalsIgnoreCase(chart.getType())).collect(Collectors.toList()));
}
}
Loading

0 comments on commit d2f7ba3

Please sign in to comment.