Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import:
- package: github.com/emicklei/go-restful
version: ~1.2.0
subpackages:
- swagger
- log
- package: github.com/emicklei/go-restful-swagger12
version: ~1.0.1
- package: github.com/Sirupsen/logrus
version: ~0.10.0
- package: k8s.io/helm
Expand Down
11 changes: 11 additions & 0 deletions internal/client/tiller-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ func (tc *TillerClient) InstallRelease(req *tiller.InstallReleaseRequest) (res *
return
}

// UpdateRelease updates a release
func (tc *TillerClient) UpdateRelease(req *tiller.UpdateReleaseRequest) (res *tiller.UpdateReleaseResponse, err error) {
tc.execute(func(rsc tiller.ReleaseServiceClient) {
res, err = rsc.UpdateRelease(tc.context, req)
if err != nil {
log.Debug("unable to update release")
}
})
return
}

// UninstallRelease uninstalls a release
func (tc *TillerClient) UninstallRelease(req *tiller.UninstallReleaseRequest) (res *tiller.UninstallReleaseResponse, err error) {
tc.execute(func(rsc tiller.ReleaseServiceClient) {
Expand Down
62 changes: 49 additions & 13 deletions internal/controller/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,10 @@ import (
tiller "k8s.io/helm/pkg/proto/hapi/services"

"fmt"

"github.com/AcalephStorage/rudder/internal/client"
)

// GetReleaseResponse contains the response for requesting Release information
type GetReleaseResponse struct {
Content *tiller.GetReleaseContentResponse `json:"content"`
Status *tiller.GetReleaseStatusResponse `json:"status"`
}

// ReleaseController handles helm release related operations
type ReleaseController struct {
tillerClient *client.TillerClient
Expand Down Expand Up @@ -82,6 +77,46 @@ func (rc *ReleaseController) InstallRelease(name, namespace, repo, chart, versio
return res, nil
}

// UpdateRelease updates a release with the provided chart
func (rc *ReleaseController) UpdateRelease(name, repo, chart, version string, values map[string]interface{}) (*tiller.UpdateReleaseResponse, error) {
chartDetails, err := rc.repoController.ChartDetails(repo, chart, version)
if err != nil {
log.WithError(err).Error("unable to get chart details")
return nil, err
}
tarball := chartDetails.ChartFile

inChart, err := chartutil.LoadFile(tarball)
if err != nil {
log.WithError(err).Error("unable to load chart details")
return nil, err
}
raw, _ := yaml.Marshal(values)

inValues := make(map[string]*hapi_chart.Value)
for k, v := range values {
inValues[k] = &hapi_chart.Value{Value: fmt.Sprintf("%v", v)}
}

config := &hapi_chart.Config{
Raw: string(raw),
Values: inValues,
}

req := &tiller.UpdateReleaseRequest{
Name: name,
Chart: inChart,
Values: config,
}

res, err := rc.tillerClient.UpdateRelease(req)
if err != nil {
log.WithError(err).Error("unable to update release")
return nil, err
}
return res, nil
}

// UninstallRelease uninstall a release
func (rc *ReleaseController) UninstallRelease(releaseName string, purge bool) (*tiller.UninstallReleaseResponse, error) {
req := &tiller.UninstallReleaseRequest{
Expand All @@ -98,7 +133,7 @@ func (rc *ReleaseController) UninstallRelease(releaseName string, purge bool) (*
}

// GetRelease returns the release details
func (rc *ReleaseController) GetRelease(name string, version int32) (*GetReleaseResponse, error) {
func (rc *ReleaseController) GetRelease(name string, version int32) (*tiller.GetReleaseContentResponse, error) {
req := &tiller.GetReleaseContentRequest{
Name: name,
Version: version,
Expand All @@ -108,18 +143,19 @@ func (rc *ReleaseController) GetRelease(name string, version int32) (*GetRelease
log.WithError(err).Error("unable to get release content")
return nil, err
}
return content, nil
}

req2 := &tiller.GetReleaseStatusRequest{
// GetReleaseStatus returns the release status
func (rc *ReleaseController) GetReleaseStatus(name string, version int32) (*tiller.GetReleaseStatusResponse, error) {
req := &tiller.GetReleaseStatusRequest{
Name: name,
Version: version,
}
status, err := rc.tillerClient.GetReleaseStatus(req2)
status, err := rc.tillerClient.GetReleaseStatus(req)
if err != nil {
log.WithError(err).Error("unable to get release status")
return nil, err
}
return &GetReleaseResponse{
Content: content,
Status: status,
}, nil
return status, nil
}
71 changes: 61 additions & 10 deletions internal/resource/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ var (
var (
errFailToListReleases = restful.NewError(http.StatusBadRequest, "unable to get list of releases")
errFailToInstallRelease = restful.NewError(http.StatusInternalServerError, "unable to install releases")
errFailToUpdateRelease = restful.NewError(http.StatusInternalServerError, "unable to update releases")
errFailtToUninstallRelease = restful.NewError(http.StatusInternalServerError, "unable to uninstall releases")
errFailToGetRelease = restful.NewError(http.StatusInternalServerError, "unable to get release content and status")
errFailToGetRelease = restful.NewError(http.StatusInternalServerError, "unable to get release content")
errFailToGetReleaseStatus = restful.NewError(http.StatusInternalServerError, "unable to get release status")
)

// InstallReleaseRequest is the request body needed for installing a new release
Expand All @@ -51,6 +53,15 @@ type InstallReleaseRequest struct {
Values map[string]interface{} `json:"values"`
}

// UpdateReleaseRequest is the request body needed for updating an existing release
type UpdateReleaseRequest struct {
Name string `json:"name"`
Repo string `json:"repo"`
Chart string `json:"chart"`
Version string `json:"version"`
Values map[string]interface{} `json:"values"`
}

// ReleaseResource represents helm releases
type ReleaseResource struct {
controller *controller.ReleaseController
Expand Down Expand Up @@ -89,6 +100,13 @@ func (rr *ReleaseResource) Register(container *restful.Container) {
Reads(InstallReleaseRequest{}).
Writes(tiller.InstallReleaseResponse{}))

// PUT /api/v1/releases
ws.Route(ws.PUT("").To(rr.updateRelease).
Doc("update release. defaults: version=latest.").
Operation("udpateRelease").
Reads(InstallReleaseRequest{}).
Writes(tiller.UpdateReleaseResponse{}))

// DELETE /api/v1/releases/{release}
ws.Route(ws.DELETE("/{release}").To(rr.uninstallRelease).
Doc("uninstall release").
Expand All @@ -102,7 +120,15 @@ func (rr *ReleaseResource) Register(container *restful.Container) {
Operation("getRelease").
Param(ws.PathParameter("release", "the release name")).
Param(ws.PathParameter("version", "the release version")).
Writes(controller.GetReleaseResponse{}))
Writes(tiller.GetReleaseContentResponse{}))

// GET /api/v1/releases/{release}/{version}
ws.Route(ws.GET("/{release}/{version}/status").To(rr.getReleaseStatus).
Doc("get release status").
Operation("getReleaseStatus").
Param(ws.PathParameter("release", "the release name")).
Param(ws.PathParameter("version", "the release version")).
Writes(tiller.GetReleaseStatusResponse{}))

container.Add(ws)

Expand Down Expand Up @@ -171,6 +197,25 @@ func (rr *ReleaseResource) installRelease(req *restful.Request, res *restful.Res
}
}

// updateRelease updates the release with the provided chart
func (rr *ReleaseResource) updateRelease(req *restful.Request, res *restful.Response) {
in := UpdateReleaseRequest{
Version: "latest",
}
if err := req.ReadEntity(&in); err != nil {
errorResponse(res, errFailToReadResponse)
return
}
out, err := rr.controller.UpdateRelease(in.Name, in.Repo, in.Chart, in.Version, in.Values)
if err != nil {
errorResponse(res, errFailToUpdateRelease)
return
}
if err := res.WriteEntity(out); err != nil {
errorResponse(res, errFailToWriteResponse)
}
}

// uninstallRelease removes the release from the list of releases
func (rr *ReleaseResource) uninstallRelease(req *restful.Request, res *restful.Response) {
releaseName := req.PathParameter("release")
Expand Down Expand Up @@ -200,17 +245,23 @@ func (rr *ReleaseResource) getRelease(req *restful.Request, res *restful.Respons
if err := res.WriteEntity(out); err != nil {
errorResponse(res, errFailToWriteResponse)
}

}

// GET api/v1/releases/:name/:version/:status {create request body}
func (rr *ReleaseResource) releaseStatus(req *restful.Request, res *restful.Response) {
// TODO
}
// getReleaseStatus returns the status of the provided release
func (rr *ReleaseResource) getReleaseStatus(req *restful.Request, res *restful.Response) {
name := req.PathParameter("release")
versionRaw := req.PathParameter("version")
version := util.ToInt32(versionRaw)

// PUT api/v1/releases {request body passed}
func (rr *ReleaseResource) updateRelease(req *restful.Request, res *restful.Response) {
// TODO
out, err := rr.controller.GetReleaseStatus(name, version)
if err != nil {
errorResponse(res, errFailToGetReleaseStatus)
return
}

if err := res.WriteEntity(out); err != nil {
errorResponse(res, errFailToWriteResponse)
}
}

// POST ??? I DUNNOT KNOW
Expand Down