Skip to content

Commit

Permalink
Enable "multi-tenancy" lookup of terraform objects (#3606)
Browse files Browse the repository at this point in the history
* Enable "multi-tenancy" lookup of terraform objects

- Search across multiple namespaces using the OSS querier instead of
  doing a cluster-level (kubectl get -A) query which tenants won't have
  permissions to do.

* Adds example RBAC for the `wge` group in gitlab which most ww devs are a part of

* Add comment to test helper
  • Loading branch information
foot authored Nov 9, 2023
1 parent 3e09ac2 commit ba44c08
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cmd/clusters-service/app/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func runServer(t *testing.T, ctx context.Context, k client.Client, ns string, ad
scs.New(),
),
app.WithKubernetesClientSet(clientSet),
app.WithClustersManager(grpctesting.MakeClustersManager(k)),
app.WithClustersManager(grpctesting.MakeClustersManager(k, nil)),
app.WithManagemetFetcher(mgmtFetcher),
)
t.Logf("%v", err)
Expand Down
14 changes: 11 additions & 3 deletions internal/grpctesting/grpctesting.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,17 @@ func BuildScheme() *runtime.Scheme {
func MakeFactoryWithObjects(objects ...client.Object) (client.Client, *clustersmngrfakes.FakeClustersManager) {
k8s := fake.NewClientBuilder().WithScheme(BuildScheme()).WithObjects(objects...).WithStatusSubresource(&tfctrl.Terraform{}).Build()

factory := MakeClustersManager(k8s)
factory := MakeClustersManager(k8s, nil)

return k8s, factory
}

func MakeClustersManager(k8s client.Client, clusters ...string) *clustersmngrfakes.FakeClustersManager {
// MakeClustersManager creates a fake ClustersManager for testing
// Pass in nsMap to give the test "principal" access to more namespaces on clusters e.g.
// "Default": {corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}}
// will search for resources in ns: "default" on the "Default" cluster.
// By default ("nil"), no namespaces will be searched.
func MakeClustersManager(k8s client.Client, nsMap map[string][]v1.Namespace, clusters ...string) *clustersmngrfakes.FakeClustersManager {
clientsPool := &clustersmngrfakes.FakeClientsPool{}

clientsPool.ClientsReturns(map[string]client.Client{"Default": k8s})
Expand All @@ -67,7 +72,10 @@ func MakeClustersManager(k8s client.Client, clusters ...string) *clustersmngrfak
return nil, clustersmngr.ClusterNotFoundError{Cluster: s}
}

nsMap := map[string][]v1.Namespace{"Default": {}}
// default no namespaces
if nsMap == nil {
nsMap = map[string][]v1.Namespace{"Default": {}}
}
clustersClient := clustersmngr.NewClient(clientsPool, nsMap, logr.Discard())

factory := &clustersmngrfakes.FakeClustersManager{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pipelines/server/approve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestApprovePipeline(t *testing.T) {
pipelineNamespace := pipetesting.NewNamespace(ctx, t, kclient)
targetNamespace := pipetesting.NewNamespace(ctx, t, kclient)

factory := grpctesting.MakeClustersManager(kclient, "management", fmt.Sprintf("%s/cluster-1", pipelineNamespace.Name))
factory := grpctesting.MakeClustersManager(kclient, nil, "management", fmt.Sprintf("%s/cluster-1", pipelineNamespace.Name))

// Setup pipeline controller server
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/pipelines/server/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestGetPipeline(t *testing.T) {
pipelineNamespace := pipetesting.NewNamespace(ctx, t, kclient)
targetNamespace := pipetesting.NewNamespace(ctx, t, kclient)

factory := grpctesting.MakeClustersManager(kclient, "management", fmt.Sprintf("%s/cluster-1", pipelineNamespace.Name))
factory := grpctesting.MakeClustersManager(kclient, nil, "management", fmt.Sprintf("%s/cluster-1", pipelineNamespace.Name))
serverClient := pipetesting.SetupServer(t, factory, kclient, "management", "", nil)

hr := createHelmRelease(ctx, t, kclient, "app-1", targetNamespace.Name)
Expand Down
2 changes: 1 addition & 1 deletion pkg/pipelines/server/list_prs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestGetListPullRequest(t *testing.T) {
prs := []*git.PullRequest{gitfakes.NewPullRequest(0, "testing", pipelineNamespace.Name+"/pipe-2/env-1", "http://example.com/foo/bar/pulls/1", false, "main")}
fakeGitProvider := gitfakes.NewFakeGitProvider("", nil, nil, nil, prs)

factory := grpctesting.MakeClustersManager(kclient, "management", fmt.Sprintf("%s/cluster-1", pipelineNamespace.Name))
factory := grpctesting.MakeClustersManager(kclient, nil, "management", fmt.Sprintf("%s/cluster-1", pipelineNamespace.Name))
serverClient := pipetesting.SetupServer(t, factory, kclient, "management", "", fakeGitProvider)

res, err := serverClient.ListPullRequests(context.Background(), &pb.ListPullRequestsRequest{
Expand Down
2 changes: 1 addition & 1 deletion pkg/terraform/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (s *server) ListTerraformObjects(ctx context.Context, msg *pb.ListTerraform

listErrors := []*pb.TerraformListError{}

if err := c.ClusteredList(ctx, clist, false, opts...); err != nil {
if err := c.ClusteredList(ctx, clist, true, opts...); err != nil {
var errs clustersmngr.ClusteredListError

if !errors.As(err, &errs) {
Expand Down
11 changes: 10 additions & 1 deletion pkg/terraform/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import (
"google.golang.org/grpc"
corev1 "k8s.io/api/core/v1"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func TestListTerraformObjects(t *testing.T) {
Expand Down Expand Up @@ -269,7 +271,14 @@ func TestReplanTerraformObject(t *testing.T) {
}

func setup(t *testing.T) (pb.TerraformClient, client.Client) {
k8s, factory := grpctesting.MakeFactoryWithObjects()
k8s := fake.NewClientBuilder().WithScheme(grpctesting.BuildScheme()).WithStatusSubresource(&tfctrl.Terraform{}).Build()

namespaces := map[string][]corev1.Namespace{
"Default": {corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}}},
}

factory := grpctesting.MakeClustersManager(k8s, namespaces)

opts := terraform.ServerOpts{
ClientsFactory: factory,
}
Expand Down
25 changes: 25 additions & 0 deletions tools/dev-resources/gitlab-wge-rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gitlab-wge-cluster-admin
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: Group
name: wge
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gitlab-wge-cluster-admin
namespace: flux-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: Group
name: wge
7 changes: 7 additions & 0 deletions tools/dev-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ config:
# auth:
# noAuthentication:
# user: "wego-admin"
#
# un-comment to enable OIDC against dex-01
# oidc:
# enabled: true
# issuerURL: "https://dex-01.wge.dev.weave.works"
# redirectURL: "http://localhost:3000/oauth2/callback"
# clientCredentialsSecret: "oidc-auth"

tls:
enabled: false
Expand Down

0 comments on commit ba44c08

Please sign in to comment.