diff --git a/README.md b/README.md index b9813cea..0483f439 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Powered by some great Go technology: - `GET /api/charts` - list all charts - `GET /api/charts/` - list all versions of a chart - `GET /api/charts//` - describe a chart version +- `GET /api/charts///templates` - get chart template +- `GET /api/charts///values` - get chart values - `HEAD /api/charts/` - check if chart exists (any versions) - `HEAD /api/charts//` - check if chart version exists diff --git a/pkg/chartmuseum/server/multitenant/handlers.go b/pkg/chartmuseum/server/multitenant/handlers.go index fbaf4505..ba5009ad 100644 --- a/pkg/chartmuseum/server/multitenant/handlers.go +++ b/pkg/chartmuseum/server/multitenant/handlers.go @@ -19,6 +19,7 @@ package multitenant import ( "bytes" "fmt" + "helm.sh/helm/v3/pkg/chart/loader" "io" "net/http" pathutil "path" @@ -116,7 +117,57 @@ func (server *MultiTenantServer) getStorageObjectRequestHandler(c *gin.Context) } c.Data(200, storageObject.ContentType, storageObject.Content) } +func (server *MultiTenantServer) getStorageObjectTemplateRequestHandler(c *gin.Context) { + repo := c.Param("repo") + name := c.Param("name") + version := c.Param("version") + filename := fmt.Sprintf("%s-%s.tgz", name, version) + + log := server.Logger.ContextLoggingFn(c) + storageObject, err := server.getStorageObject(log, repo, filename) + if err != nil { + c.JSON(err.Status, gin.H{"error": err.Message}) + return + } + chrt, err1 := loader.LoadArchive(bytes.NewReader(storageObject.Content)) + if err1 != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err1}) + return + } + c.JSON(200, map[string]interface{}{ + "templates": chrt.Templates, + "values": chrt.Values, + }) +} +func (server *MultiTenantServer) getStorageObjectValuesRequestHandler(c *gin.Context) { + repo := c.Param("repo") + name := c.Param("name") + version := c.Param("version") + filename := fmt.Sprintf("%s-%s.tgz", name, version) + log := server.Logger.ContextLoggingFn(c) + storageObject, err := server.getStorageObject(log, repo, filename) + if err != nil { + c.JSON(err.Status, gin.H{"error": err.Message}) + return + } + chrt, err1 := loader.LoadArchive(bytes.NewReader(storageObject.Content)) + if err1 != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err1}) + return + } + var data []byte + for _, file := range chrt.Raw { + if file.Name == "values.yaml" { + data = file.Data + } + } + if data == nil { + c.JSON(http.StatusNotFound, gin.H{"error": "values.yaml not found"}) + return + } + c.Data(200, "application/yaml", data) +} func (server *MultiTenantServer) getAllChartsRequestHandler(c *gin.Context) { repo := c.Param("repo") offset := 0 diff --git a/pkg/chartmuseum/server/multitenant/routes.go b/pkg/chartmuseum/server/multitenant/routes.go index 619011cd..dc11d02c 100644 --- a/pkg/chartmuseum/server/multitenant/routes.go +++ b/pkg/chartmuseum/server/multitenant/routes.go @@ -42,6 +42,8 @@ func (s *MultiTenantServer) Routes() []*cm_router.Route { {"GET", "/api/:repo/charts/:name", s.getChartRequestHandler, cm_auth.PullAction}, {"HEAD", "/api/:repo/charts/:name/:version", s.headChartVersionRequestHandler, cm_auth.PullAction}, {"GET", "/api/:repo/charts/:name/:version", s.getChartVersionRequestHandler, cm_auth.PullAction}, + {"GET", "/api/:repo/charts/:name/:version/templates", s.getStorageObjectTemplateRequestHandler, cm_auth.PullAction}, + {"GET", "/api/:repo/charts/:name/:version/values", s.getStorageObjectValuesRequestHandler, cm_auth.PullAction}, {"POST", "/api/:repo/charts", s.postRequestHandler, cm_auth.PushAction}, {"POST", "/api/:repo/prov", s.postProvenanceFileRequestHandler, cm_auth.PushAction}, }