Skip to content

Commit

Permalink
Filter resources before returning to the client
Browse files Browse the repository at this point in the history
Filter resources returned from the REST and WebSocket APIs before
returning them to the client.

Ensure the status code is returned correctly.
  • Loading branch information
AlanGreene authored and Megan-Wright committed May 13, 2020
1 parent 4bfdcea commit 69574f4
Show file tree
Hide file tree
Showing 17 changed files with 129 additions and 73 deletions.
2 changes: 1 addition & 1 deletion base/200-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ rules:
resources: ["pods/log", "namespaces", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets", "configmaps"]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
Expand Down
15 changes: 14 additions & 1 deletion overlays/full-fat/cluster-role-patch-json.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- create
Expand Down Expand Up @@ -122,3 +121,17 @@
- delete
- patch
- add
- op: add
path: /rules/9
value:
apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete
2 changes: 1 addition & 1 deletion pkg/controllers/kubernetes/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package kubernetes

import (
"github.com/tektoncd/dashboard/pkg/broadcaster"
"github.com/tektoncd/dashboard/pkg/controllers/utils"
"github.com/tektoncd/dashboard/pkg/endpoints"
"github.com/tektoncd/dashboard/pkg/logging"
"github.com/tektoncd/dashboard/pkg/router"
"github.com/tektoncd/dashboard/pkg/utils"
v1 "k8s.io/api/core/v1"
k8sinformer "k8s.io/client-go/informers"
"k8s.io/client-go/tools/cache"
Expand Down
1 change: 1 addition & 0 deletions pkg/controllers/kubernetes/namespaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func NewNamespaceController(sharedK8sInformerFactory k8sinformer.SharedInformerF
broadcaster.NamespaceCreated,
broadcaster.NamespaceUpdated,
broadcaster.NamespaceDeleted,
nil,
)
}
6 changes: 4 additions & 2 deletions pkg/controllers/kubernetes/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package kubernetes

import (
"github.com/tektoncd/dashboard/pkg/broadcaster"
"github.com/tektoncd/dashboard/pkg/controllers/utils"
controllerUtils "github.com/tektoncd/dashboard/pkg/controllers/utils"
"github.com/tektoncd/dashboard/pkg/logging"
"github.com/tektoncd/dashboard/pkg/utils"
k8sinformer "k8s.io/client-go/informers"
)

Expand All @@ -12,11 +13,12 @@ import (
func NewSecretController(sharedK8sInformerFactory k8sinformer.SharedInformerFactory) {
logging.Log.Debug("In NewSecretController")

utils.NewController(
controllerUtils.NewController(
"secret",
sharedK8sInformerFactory.Core().V1().Secrets().Informer(),
broadcaster.SecretCreated,
broadcaster.SecretUpdated,
broadcaster.SecretDeleted,
utils.SanitizeSecret,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/kubernetes/serviceAccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ func NewServiceAccountController(sharedK8sInformerFactory k8sinformer.SharedInfo
broadcaster.ServiceAccountCreated,
broadcaster.ServiceAccountUpdated,
broadcaster.ServiceAccountDeleted,
nil,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/tekton/clustertask.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ func NewClusterTaskController(sharedTektonInformerFactory tektoninformer.SharedI
broadcaster.ClusterTaskCreated,
broadcaster.ClusterTaskUpdated,
broadcaster.ClusterTaskDeleted,
nil,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/tekton/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func NewPipelineController(sharedTektonInformerFactory tektoninformer.SharedInfo
broadcaster.PipelineCreated,
broadcaster.PipelineUpdated,
broadcaster.PipelineDeleted,
nil,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/tekton/pipelineresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func NewPipelineResourceController(sharedTektonInformerFactory tektonresourceinf
broadcaster.PipelineResourceCreated,
broadcaster.PipelineResourceUpdated,
broadcaster.PipelineResourceDeleted,
nil,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/tekton/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func NewPipelineRunController(sharedTektonInformerFactory tektoninformer.SharedI
broadcaster.PipelineRunCreated,
broadcaster.PipelineRunUpdated,
broadcaster.PipelineRunDeleted,
nil,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/tekton/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func NewTaskController(sharedTektonInformerFactory tektoninformer.SharedInformer
broadcaster.TaskCreated,
broadcaster.TaskUpdated,
broadcaster.TaskDeleted,
nil,
)
}
1 change: 1 addition & 0 deletions pkg/controllers/tekton/taskrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func NewTaskRunController(sharedTektonInformerFactory tektoninformer.SharedInfor
broadcaster.TaskRunCreated,
broadcaster.TaskRunUpdated,
broadcaster.TaskRunDeleted,
nil,
)
}
17 changes: 12 additions & 5 deletions pkg/controllers/utils/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@ import (
"github.com/tektoncd/dashboard/pkg/broadcaster"
"github.com/tektoncd/dashboard/pkg/endpoints"
"github.com/tektoncd/dashboard/pkg/logging"
"github.com/tektoncd/dashboard/pkg/utils"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
)

func NewController(kind string, informer cache.SharedIndexInformer, onCreated, onUpdated, onDeleted broadcaster.MessageType) {
func NewController(kind string, informer cache.SharedIndexInformer, onCreated, onUpdated, onDeleted broadcaster.MessageType, filter func(interface{}, bool) interface{}) {
logging.Log.Debug("In NewController")

if filter == nil {
filter = func(obj interface{}, skipDeletedCheck bool) interface{} {
return obj
}
}

informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
logging.Log.Debugf("Controller detected %s '%s' created", kind, obj.(metav1.Object).GetName())
data := broadcaster.SocketData{
MessageType: onCreated,
Payload: obj,
Payload: filter(obj, true),
}
endpoints.ResourcesChannel <- data
},
Expand All @@ -27,16 +34,16 @@ func NewController(kind string, informer cache.SharedIndexInformer, onCreated, o
logging.Log.Debugf("Controller detected %s '%s' updated", kind, oldSecret.GetName())
data := broadcaster.SocketData{
MessageType: onUpdated,
Payload: newObj,
Payload: filter(newObj, true),
}
endpoints.ResourcesChannel <- data
}
},
DeleteFunc: func(obj interface{}) {
logging.Log.Debugf("Controller detected %s '%s' deleted", kind, GetDeletedObjectMeta(obj).GetName())
logging.Log.Debugf("Controller detected %s '%s' deleted", kind, utils.GetDeletedObjectMeta(obj).GetName())
data := broadcaster.SocketData{
MessageType: onDeleted,
Payload: obj,
Payload: filter(obj, false),
}
endpoints.ResourcesChannel <- data
},
Expand Down
47 changes: 0 additions & 47 deletions pkg/controllers/utils/utils.go

This file was deleted.

8 changes: 7 additions & 1 deletion pkg/endpoints/cluster.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019 The Tekton Authors
Copyright 2019-2020 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -22,6 +22,7 @@ import (
"strings"

restful "github.com/emicklei/go-restful"
"github.com/gorilla/csrf"
"github.com/tektoncd/dashboard/pkg/logging"
"github.com/tektoncd/dashboard/pkg/utils"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -206,3 +207,8 @@ func (r Resource) GetProperties(request *restful.Request, response *restful.Resp

response.WriteEntity(properties)
}

func (r Resource) GetToken(request *restful.Request, response *restful.Response) {
response.Header().Add("X-CSRF-Token", csrf.Token(request.Request))
response.Write([]byte("OK"))
}
58 changes: 58 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import (

restful "github.com/emicklei/go-restful"
logging "github.com/tektoncd/dashboard/pkg/logging"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
)

// RespondError - logs and writes an error response with a desired status code
Expand Down Expand Up @@ -69,3 +74,56 @@ func GetContentType(content []byte) string {
}
return "text/plain"
}

// Adapted from https://github.com/kubernetes-sigs/controller-runtime/blob/v0.5.2/pkg/source/internal/eventsource.go#L131-L149
func GetDeletedObjectMeta(obj interface{}) metav1.Object {
// Deal with tombstone events by pulling the object out. Tombstone events wrap the object in a
// DeleteFinalStateUnknown struct, so the object needs to be pulled out.
// Copied from sample-controller
// This should only happen when we're missing events.
if _, ok := obj.(metav1.Object); !ok {
// If the object doesn't have Metadata, assume it is a tombstone object of type DeletedFinalStateUnknown
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); !ok {
logging.Log.Errorf("Error decoding object: Expected cache.DeletedFinalStateUnknown, got %T", obj)
return &metav1.ObjectMeta{}
} else {
// Set obj to the tombstone obj
obj = tombstone.Obj
}
}

// Pull metav1.Object out of the object
if o, err := meta.Accessor(obj); err != nil {
logging.Log.Errorf("Missing meta for object %T: %v", obj, err)
return &metav1.ObjectMeta{}
} else {
return o
}
}

func SanitizeSecret(obj interface{}, skipDeletedCheck bool) interface{} {
if !skipDeletedCheck {
obj = GetDeletedObjectMeta(obj)
}

secret, ok := obj.(*corev1.Secret)
if !ok {
return obj
}

logging.Log.Debug("Sanitizing Secret")
data := make(map[string][]byte)
if secret.Data["username"] != nil {
data["username"] = secret.Data["username"]
}
if secret.Data["accessToken"] != nil {
data["accessToken"] = []byte("--- REDACTED ---")
}
return corev1.Secret{
secret.TypeMeta,
secret.ObjectMeta,
data,
nil, // StringData, never returned over API
secret.Type,
}
}
39 changes: 24 additions & 15 deletions src/containers/SideNav/SideNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,21 +272,30 @@ class SideNav extends Component {
})}
</SideNavLink>
)}

<SideNavLink
element={NavLink}
icon={<span />}
to={this.getPath(urls.secrets.all())}
>
Secrets
</SideNavLink>
<SideNavLink
element={NavLink}
icon={<span />}
to={this.getPath(urls.serviceAccounts.all())}
>
ServiceAccounts
</SideNavLink>
{!this.props.isReadOnly && (
<SideNavMenu
defaultExpanded
title={intl.formatMessage({
id: 'dashboard.sideNav.kubernetesResources',
defaultMessage: 'Kubernetes resources'
})}
>
<SideNavMenuItem
element={NavLink}
icon={<span />}
to={this.getPath(urls.secrets.all())}
>
Secrets
</SideNavMenuItem>
<SideNavMenuItem
element={NavLink}
icon={<span />}
to={this.getPath(urls.serviceAccounts.all())}
>
ServiceAccounts
</SideNavMenuItem>
</SideNavMenu>
)}
<>
{extensions.length > 0 &&
extensions.map(
Expand Down

0 comments on commit 69574f4

Please sign in to comment.