Skip to content

Commit

Permalink
feat: Implement the GetHelmRelease endpoint
Browse files Browse the repository at this point in the history
Add endpoint to get a single HelmRelease.

Additional changes:

* Moved `ListHelmReleases` and `GetHelmRelease` endpoint definitions into
  their own file, to get a better separation (`helm.go`).
* Moved the tests for `ListHelmReleases` and `GetHelmRelease` endpoints into
  the corresponding test file (`helm_test.go`).

Closes #1498
  • Loading branch information
yitsushi committed Feb 25, 2022
1 parent 576f0a4 commit 88af153
Show file tree
Hide file tree
Showing 10 changed files with 876 additions and 398 deletions.
21 changes: 21 additions & 0 deletions api/core/core.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ service Core {
get : "/v1/kustomizations/{name}"
};
}

/*
* ListHelmReleases lists helm releases from a cluster.
*/
Expand All @@ -48,6 +49,17 @@ service Core {
};
}


/*
* GetHelmRelease gets data about a single HelmRelease from the cluster.
*/
rpc GetHelmRelease(GetHelmReleaseRequest) returns (GetHelmReleaseResponse) {
option (google.api.http) = {
get : "/v1/helmrelease/{name}"
};
}


// Sources

/*
Expand Down Expand Up @@ -143,6 +155,15 @@ message ListHelmReleasesResponse {
repeated HelmRelease helm_releases = 1;
}

message GetHelmReleaseRequest {
string name = 1;
string namespace = 2;
}

message GetHelmReleaseResponse {
HelmRelease helm_release = 1;
}

message ListGitRepositoriesRequest {
string namespace = 1;
}
Expand Down
45 changes: 45 additions & 0 deletions api/core/core.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,43 @@
]
}
},
"/v1/helmrelease/{name}": {
"get": {
"summary": "GetHelmRelease gets data about a single HelmRelease from the cluster.",
"operationId": "Core_GetHelmRelease",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/v1GetHelmReleaseResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "namespace",
"in": "query",
"required": false,
"type": "string"
}
],
"tags": [
"Core"
]
}
},
"/v1/helmreleases": {
"get": {
"summary": "ListHelmReleases lists helm releases from a cluster.",
Expand Down Expand Up @@ -545,6 +582,14 @@
}
}
},
"v1GetHelmReleaseResponse": {
"type": "object",
"properties": {
"helmRelease": {
"$ref": "#/definitions/v1HelmRelease"
}
}
},
"v1GetKustomizationResponse": {
"type": "object",
"properties": {
Expand Down
23 changes: 0 additions & 23 deletions core/server/automations.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
"github.com/weaveworks/weave-gitops/core/server/types"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
Expand Down Expand Up @@ -57,25 +56,3 @@ func (cs *coreServer) GetKustomization(ctx context.Context, msg *pb.GetKustomiza

return &pb.GetKustomizationResponse{Kustomization: res}, nil
}

func (cs *coreServer) ListHelmReleases(ctx context.Context, msg *pb.ListHelmReleasesRequest) (*pb.ListHelmReleasesResponse, error) {
k8s, err := cs.k8s.Client(ctx)
if err != nil {
return nil, doClientError(err)
}

l := &helmv2.HelmReleaseList{}

if err := list(ctx, k8s, temporarilyEmptyAppName, msg.Namespace, l); err != nil {
return nil, err
}

var results []*pb.HelmRelease
for _, repository := range l.Items {
results = append(results, types.HelmReleaseToProto(&repository))
}

return &pb.ListHelmReleasesResponse{
HelmReleases: results,
}, nil
}
40 changes: 0 additions & 40 deletions core/server/automations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"k8s.io/apimachinery/pkg/util/rand"
"sigs.k8s.io/controller-runtime/pkg/client"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
. "github.com/onsi/gomega"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
Expand Down Expand Up @@ -129,45 +128,6 @@ func TestGetKustomization(t *testing.T) {
})
}

func TestListHelmReleases(t *testing.T) {
g := NewGomegaWithT(t)

ctx := context.Background()

c, cleanup := makeGRPCServer(k8sEnv.Rest, t)
defer cleanup()

_, k, err := kube.NewKubeHTTPClientWithConfig(k8sEnv.Rest, "")
g.Expect(err).NotTo(HaveOccurred())

appName := "myapp"
ns := newNamespace(ctx, k, g)

hr := &helmv2.HelmRelease{
Spec: helmv2.HelmReleaseSpec{
Chart: helmv2.HelmChartTemplate{
Spec: helmv2.HelmChartTemplateSpec{
SourceRef: helmv2.CrossNamespaceObjectReference{
Kind: "GitRepository",
Name: "somesource",
},
},
},
},
}
hr.Name = appName
hr.Namespace = ns.Name

g.Expect(k.Create(ctx, hr)).To(Succeed())

res, err := c.ListHelmReleases(ctx, &pb.ListHelmReleasesRequest{
Namespace: ns.Name,
})
g.Expect(err).NotTo(HaveOccurred())
g.Expect(res.HelmReleases).To(HaveLen(1))
g.Expect(res.HelmReleases[0].Name).To(Equal(appName))
}

func newNamespace(ctx context.Context, k client.Client, g *GomegaWithT) *corev1.Namespace {
ns := &corev1.Namespace{}
ns.Name = "kube-test-" + rand.String(5)
Expand Down
48 changes: 48 additions & 0 deletions core/server/helm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package server

import (
"context"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
"github.com/weaveworks/weave-gitops/core/server/types"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
)

func (cs *coreServer) ListHelmReleases(ctx context.Context, msg *pb.ListHelmReleasesRequest) (*pb.ListHelmReleasesResponse, error) {
k8s, err := cs.k8s.Client(ctx)
if err != nil {
return nil, doClientError(err)
}

l := &helmv2.HelmReleaseList{}

if err := list(ctx, k8s, temporarilyEmptyAppName, msg.Namespace, l); err != nil {
return nil, err
}

var results []*pb.HelmRelease
for _, repository := range l.Items {
results = append(results, types.HelmReleaseToProto(&repository))
}

return &pb.ListHelmReleasesResponse{
HelmReleases: results,
}, nil
}

func (cs *coreServer) GetHelmRelease(ctx context.Context, msg *pb.GetHelmReleaseRequest) (*pb.GetHelmReleaseResponse, error) {
k8s, err := cs.k8s.Client(ctx)
if err != nil {
return nil, doClientError(err)
}

helmRelease := helmv2.HelmRelease{}

if err = get(ctx, k8s, msg.Name, msg.Namespace, &helmRelease); err != nil {
return nil, err
}

return &pb.GetHelmReleaseResponse{
HelmRelease: types.HelmReleaseToProto(&helmRelease),
}, nil
}
109 changes: 109 additions & 0 deletions core/server/helm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package server

import (
"context"
"testing"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
. "github.com/onsi/gomega"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
"github.com/weaveworks/weave-gitops/pkg/kube"
"k8s.io/apimachinery/pkg/util/rand"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func TestListHelmReleases(t *testing.T) {
g := NewGomegaWithT(t)
ctx := context.Background()

c, cleanup := makeGRPCServer(k8sEnv.Rest, t)
defer cleanup()

_, k, err := kube.NewKubeHTTPClientWithConfig(k8sEnv.Rest, "")
g.Expect(err).NotTo(HaveOccurred())

appName := "myapp"
ns := newNamespace(ctx, k, g)

newHelmRelease(ctx, appName, ns.Name, k, g)

res, err := c.ListHelmReleases(ctx, &pb.ListHelmReleasesRequest{
Namespace: ns.Name,
})
g.Expect(err).NotTo(HaveOccurred())
g.Expect(res.HelmReleases).To(HaveLen(1))
g.Expect(res.HelmReleases[0].Name).To(Equal(appName))
}

func TestGetHelmRelease(t *testing.T) {
g := NewGomegaWithT(t)
ctx := context.Background()

c, cleanup := makeGRPCServer(k8sEnv.Rest, t)
defer cleanup()

_, k, err := kube.NewKubeHTTPClientWithConfig(k8sEnv.Rest, "")
g.Expect(err).NotTo(HaveOccurred())

appName := "myapp" + rand.String(5)
ns1 := newNamespace(ctx, k, g)
ns2 := newNamespace(ctx, k, g)
ns3 := newNamespace(ctx, k, g)

newHelmRelease(ctx, appName, ns1.Name, k, g)
newHelmRelease(ctx, appName, ns2.Name, k, g)

// Get app from ns1.
response, err := c.GetHelmRelease(ctx, &pb.GetHelmReleaseRequest{
Name: appName,
Namespace: ns1.Name,
})

g.Expect(err).NotTo(HaveOccurred())
g.Expect(response.HelmRelease.Name).To(Equal(appName))
g.Expect(response.HelmRelease.Namespace).To(Equal(ns1.Name))

// Get app from ns2.
response, err = c.GetHelmRelease(ctx, &pb.GetHelmReleaseRequest{
Name: appName,
Namespace: ns2.Name,
})

g.Expect(err).NotTo(HaveOccurred())
g.Expect(response.HelmRelease.Name).To(Equal(appName))
g.Expect(response.HelmRelease.Namespace).To(Equal(ns2.Name))

// Get app from ns3, should fail.
response, err = c.GetHelmRelease(ctx, &pb.GetHelmReleaseRequest{
Name: appName,
Namespace: ns3.Name,
})

g.Expect(err).To(HaveOccurred())
}

func newHelmRelease(
ctx context.Context,
appName, nsName string,
k client.Client,
g *GomegaWithT,
) helmv2.HelmRelease {
release := helmv2.HelmRelease{
Spec: helmv2.HelmReleaseSpec{
Chart: helmv2.HelmChartTemplate{
Spec: helmv2.HelmChartTemplateSpec{
SourceRef: helmv2.CrossNamespaceObjectReference{
Kind: "GitRepository",
Name: "somesource",
},
},
},
},
}
release.Name = appName
release.Namespace = nsName

g.Expect(k.Create(ctx, &release)).To(Succeed())

return release
}

0 comments on commit 88af153

Please sign in to comment.