mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-08-18 08:29:36 +00:00
Add acceptance tests for k8s permissions (#834)
This commit is contained in:
parent
1597321e24
commit
c5471c501b
10
.github/workflows/acceptance_tests.yml
vendored
10
.github/workflows/acceptance_tests.yml
vendored
@ -24,6 +24,16 @@ jobs:
|
|||||||
- name: Setup acceptance test
|
- name: Setup acceptance test
|
||||||
run: source ./acceptanceTests/setup.sh
|
run: source ./acceptanceTests/setup.sh
|
||||||
|
|
||||||
|
- name: Create k8s users and change context
|
||||||
|
env:
|
||||||
|
USERNAME_UNRESTRICTED: user-with-clusterwide-access
|
||||||
|
USERNAME_RESTRICTED: user-with-restricted-access
|
||||||
|
run: |
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_UNRESTRICTED}"
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_RESTRICTED}"
|
||||||
|
kubectl apply -f cli/cmd/permissionFiles/permissions-all-namespaces-tap.yaml
|
||||||
|
kubectl config use-context ${USERNAME_UNRESTRICTED}
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: make acceptance-test
|
run: make acceptance-test
|
||||||
|
|
||||||
|
37
acceptanceTests/create_user.sh
Executable file
37
acceptanceTests/create_user.sh
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a user in Minikube cluster "minikube"
|
||||||
|
# Create context for user
|
||||||
|
# Usage:
|
||||||
|
# ./create_user.sh <username>
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
NEW_USERNAME=$1
|
||||||
|
CERT_DIR="${HOME}/certs"
|
||||||
|
KEY_FILE="${CERT_DIR}/${NEW_USERNAME}.key"
|
||||||
|
CRT_FILE="${CERT_DIR}/${NEW_USERNAME}.crt"
|
||||||
|
MINIKUBE_KEY_FILE="${HOME}/.minikube/ca.key"
|
||||||
|
MINIKUBE_CRT_FILE="${HOME}/.minikube/ca.crt"
|
||||||
|
DAYS=1
|
||||||
|
|
||||||
|
echo "Creating user and context for username \"${NEW_USERNAME}\" in Minikube cluster"
|
||||||
|
|
||||||
|
if ! command -v openssl &> /dev/null
|
||||||
|
then
|
||||||
|
echo "Installing openssl"
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install openssl
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating certificate for user \"${NEW_USERNAME}\""
|
||||||
|
mkdir -p ${CERT_DIR}
|
||||||
|
echo "Generating key \"${KEY_FILE}\""
|
||||||
|
openssl genrsa -out "${KEY_FILE}" 2048
|
||||||
|
echo "Generating crt \"${CRT_FILE}\""
|
||||||
|
openssl req -new -key "${KEY_FILE}" -out "${CRT_FILE}" -subj "/CN=${NEW_USERNAME}/O=group1"
|
||||||
|
openssl x509 -req -in "${CRT_FILE}" -CA "${MINIKUBE_CRT_FILE}" -CAkey "${MINIKUBE_KEY_FILE}" -CAcreateserial -out "${CRT_FILE}" -days $DAYS
|
||||||
|
|
||||||
|
echo "Creating context for user \"${NEW_USERNAME}\""
|
||||||
|
kubectl config set-credentials "${NEW_USERNAME}" --client-certificate="${CRT_FILE}" --client-key="${KEY_FILE}"
|
||||||
|
kubectl config set-context "${NEW_USERNAME}" --cluster=minikube --user="${NEW_USERNAME}"
|
@ -49,7 +49,13 @@ func TestRedis(t *testing.T) {
|
|||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
redisExternalIp, err := GetServiceExternalIp(ctx, defaultNamespaceName, "redis")
|
kubernetesProvider, err := NewKubernetesProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create k8s provider, err %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
redisExternalIp, err := kubernetesProvider.GetServiceExternalIp(ctx, defaultNamespaceName, "redis")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to get redis external ip, err: %v", err)
|
t.Errorf("failed to get redis external ip, err: %v", err)
|
||||||
return
|
return
|
||||||
@ -141,7 +147,13 @@ func TestAmqp(t *testing.T) {
|
|||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
rabbitmqExternalIp, err := GetServiceExternalIp(ctx, defaultNamespaceName, "rabbitmq")
|
kubernetesProvider, err := NewKubernetesProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create k8s provider, err %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rabbitmqExternalIp, err := kubernetesProvider.GetServiceExternalIp(ctx, defaultNamespaceName, "rabbitmq")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to get RabbitMQ external ip, err: %v", err)
|
t.Errorf("failed to get RabbitMQ external ip, err: %v", err)
|
||||||
return
|
return
|
||||||
|
@ -57,9 +57,6 @@ kubectl expose deployment rabbitmq --type=LoadBalancer --port=5672 -n mizu-tests
|
|||||||
echo "Starting proxy"
|
echo "Starting proxy"
|
||||||
kubectl proxy --port=8080 &
|
kubectl proxy --port=8080 &
|
||||||
|
|
||||||
echo "Starting tunnel"
|
|
||||||
minikube tunnel &
|
|
||||||
|
|
||||||
echo "Setting minikube docker env"
|
echo "Setting minikube docker env"
|
||||||
eval $(minikube docker-env)
|
eval $(minikube docker-env)
|
||||||
|
|
||||||
@ -68,3 +65,6 @@ make build-docker-ci
|
|||||||
|
|
||||||
echo "Build cli"
|
echo "Build cli"
|
||||||
make build-cli-ci
|
make build-cli-ci
|
||||||
|
|
||||||
|
echo "Starting tunnel"
|
||||||
|
minikube tunnel &
|
||||||
|
@ -14,6 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTap(t *testing.T) {
|
func TestTap(t *testing.T) {
|
||||||
|
basicTapTest(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func basicTapTest(t *testing.T, shouldCheckSrcAndDest bool, extraArgs... string) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
@ -33,6 +37,8 @@ func TestTap(t *testing.T) {
|
|||||||
tapNamespace := GetDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
|
tapCmdArgs = append(tapCmdArgs, extraArgs...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
@ -72,7 +78,6 @@ func TestTap(t *testing.T) {
|
|||||||
expectedPodsStr += fmt.Sprintf("Name:%vNamespace:%v", expectedPods[i].Name, expectedPods[i].Namespace)
|
expectedPodsStr += fmt.Sprintf("Name:%vNamespace:%v", expectedPods[i].Name, expectedPods[i].Namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
const shouldCheckSrcAndDest = false
|
|
||||||
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/UiTest.js\" --env entriesCount=%d,arrayDict=%v,shouldCheckSrcAndDest=%v",
|
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/UiTest.js\" --env entriesCount=%d,arrayDict=%v,shouldCheckSrcAndDest=%v",
|
||||||
entriesCount, expectedPodsStr, shouldCheckSrcAndDest))
|
entriesCount, expectedPodsStr, shouldCheckSrcAndDest))
|
||||||
})
|
})
|
||||||
@ -644,3 +649,44 @@ func TestTapDumpLogs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIpResolving(t *testing.T) {
|
||||||
|
namespace := allNamespaces
|
||||||
|
|
||||||
|
t.Log("add permissions for ip-resolution for current user")
|
||||||
|
if err := ApplyKubeFilesForTest(
|
||||||
|
t,
|
||||||
|
"minikube",
|
||||||
|
namespace,
|
||||||
|
"../cli/cmd/permissionFiles/permissions-all-namespaces-ip-resolution-optional.yaml",
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to create k8s permissions, %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
basicTapTest(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRestrictedMode(t *testing.T) {
|
||||||
|
namespace := "mizu-tests"
|
||||||
|
|
||||||
|
t.Log("creating permissions for restricted user")
|
||||||
|
if err := ApplyKubeFilesForTest(
|
||||||
|
t,
|
||||||
|
"minikube",
|
||||||
|
namespace,
|
||||||
|
"../cli/cmd/permissionFiles/permissions-ns-tap.yaml",
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to create k8s permissions, %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("switching k8s context to user")
|
||||||
|
if err := SwitchKubeContextForTest(t, "user-with-restricted-access"); err != nil {
|
||||||
|
t.Errorf("failed to switch k8s context, %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
extraArgs := []string{"--set", fmt.Sprintf("mizu-resources-namespace=%s", namespace)}
|
||||||
|
t.Run("basic tap", func (testingT *testing.T) {basicTapTest(testingT, false, extraArgs...)})
|
||||||
|
}
|
||||||
|
@ -31,6 +31,7 @@ const (
|
|||||||
defaultServiceName = "httpbin"
|
defaultServiceName = "httpbin"
|
||||||
defaultEntriesCount = 50
|
defaultEntriesCount = 50
|
||||||
waitAfterTapPodsReady = 3 * time.Second
|
waitAfterTapPodsReady = 3 * time.Second
|
||||||
|
allNamespaces = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
type PodDescriptor struct {
|
type PodDescriptor struct {
|
||||||
@ -74,7 +75,7 @@ func GetApiServerUrl(port uint16) string {
|
|||||||
return fmt.Sprintf("http://localhost:%v", port)
|
return fmt.Sprintf("http://localhost:%v", port)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetServiceExternalIp(ctx context.Context, namespace string, service string) (string, error) {
|
func NewKubernetesProvider() (*KubernetesProvider, error) {
|
||||||
home := homedir.HomeDir()
|
home := homedir.HomeDir()
|
||||||
configLoadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: filepath.Join(home, ".kube", "config")}
|
configLoadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: filepath.Join(home, ".kube", "config")}
|
||||||
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||||
@ -86,15 +87,23 @@ func GetServiceExternalIp(ctx context.Context, namespace string, service string)
|
|||||||
|
|
||||||
restClientConfig, err := clientConfig.ClientConfig()
|
restClientConfig, err := clientConfig.ClientConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
clientSet, err := kubernetes.NewForConfig(restClientConfig)
|
clientSet, err := kubernetes.NewForConfig(restClientConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceObj, err := clientSet.CoreV1().Services(namespace).Get(ctx, service, metav1.GetOptions{})
|
return &KubernetesProvider{clientSet}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type KubernetesProvider struct {
|
||||||
|
clientSet *kubernetes.Clientset
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kp *KubernetesProvider) GetServiceExternalIp(ctx context.Context, namespace string, service string) (string, error) {
|
||||||
|
serviceObj, err := kp.clientSet.CoreV1().Services(namespace).Get(ctx, service, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -103,6 +112,105 @@ func GetServiceExternalIp(ctx context.Context, namespace string, service string)
|
|||||||
return externalIp, nil
|
return externalIp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SwitchKubeContextForTest(t *testing.T, newContextName string) error {
|
||||||
|
prevKubeContextName, err := GetKubeCurrentContextName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetKubeCurrentContext(newContextName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := SetKubeCurrentContext(prevKubeContextName); err != nil {
|
||||||
|
t.Errorf("failed to set Kubernetes context to %s, err: %v", prevKubeContextName, err)
|
||||||
|
t.Errorf("cleanup failed, subsequent tests may be affected")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetKubeCurrentContextName() (string, error) {
|
||||||
|
cmd := exec.Command("kubectl", "config", "current-context")
|
||||||
|
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(bytes.TrimSpace(output)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKubeCurrentContext(contextName string) error {
|
||||||
|
cmd := exec.Command("kubectl", "config", "use-context", contextName)
|
||||||
|
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyKubeFilesForTest(t *testing.T, kubeContext string, namespace string, filename ...string) error {
|
||||||
|
for i := range filename {
|
||||||
|
fname := filename[i]
|
||||||
|
if err := ApplyKubeFile(kubeContext, namespace, fname); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := DeleteKubeFile(kubeContext, namespace, fname); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to delete Kubernetes resources in namespace %s from filename %s, err: %v",
|
||||||
|
namespace,
|
||||||
|
fname,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyKubeFile(kubeContext string, namespace string, filename string) (error) {
|
||||||
|
cmdArgs := []string{
|
||||||
|
"apply",
|
||||||
|
"--context", kubeContext,
|
||||||
|
"-f", filename,
|
||||||
|
}
|
||||||
|
if namespace != allNamespaces {
|
||||||
|
cmdArgs = append(cmdArgs, "-n", namespace)
|
||||||
|
}
|
||||||
|
cmd := exec.Command("kubectl", cmdArgs...)
|
||||||
|
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteKubeFile(kubeContext string, namespace string, filename string) error {
|
||||||
|
cmdArgs := []string{
|
||||||
|
"delete",
|
||||||
|
"--context", kubeContext,
|
||||||
|
"-f", filename,
|
||||||
|
}
|
||||||
|
if namespace != allNamespaces {
|
||||||
|
cmdArgs = append(cmdArgs, "-n", namespace)
|
||||||
|
}
|
||||||
|
cmd := exec.Command("kubectl", cmdArgs...)
|
||||||
|
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func getDefaultCommandArgs() []string {
|
func getDefaultCommandArgs() []string {
|
||||||
setFlag := "--set"
|
setFlag := "--set"
|
||||||
telemetry := "telemetry=false"
|
telemetry := "telemetry=false"
|
||||||
|
@ -17,7 +17,7 @@ metadata:
|
|||||||
name: mizu-runner-debug-clusterrolebindings
|
name: mizu-runner-debug-clusterrolebindings
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-clusterwide-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
|
@ -29,7 +29,7 @@ metadata:
|
|||||||
name: mizu-resolver-clusterrolebindings
|
name: mizu-resolver-clusterrolebindings
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-clusterwide-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
|
@ -22,6 +22,9 @@ rules:
|
|||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["configmaps"]
|
resources: ["configmaps"]
|
||||||
verbs: ["create"]
|
verbs: ["create"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods/log"]
|
||||||
|
verbs: ["get"]
|
||||||
---
|
---
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
@ -29,7 +32,7 @@ metadata:
|
|||||||
name: mizu-runner-clusterrolebindings
|
name: mizu-runner-clusterrolebindings
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-clusterwide-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
|
@ -3,7 +3,6 @@ kind: Role
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-runner-debug-role
|
name: mizu-runner-debug-role
|
||||||
namespace: user1
|
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: ["events.k8s.io"]
|
- apiGroups: ["events.k8s.io"]
|
||||||
resources: ["events"]
|
resources: ["events"]
|
||||||
@ -16,10 +15,9 @@ kind: RoleBinding
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-runner-debug-rolebindings
|
name: mizu-runner-debug-rolebindings
|
||||||
namespace: user1
|
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-restricted-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: Role
|
kind: Role
|
||||||
|
@ -3,7 +3,6 @@ kind: Role
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-resolver-role
|
name: mizu-resolver-role
|
||||||
namespace: user1
|
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["serviceaccounts"]
|
resources: ["serviceaccounts"]
|
||||||
@ -28,10 +27,9 @@ kind: RoleBinding
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-resolver-rolebindings
|
name: mizu-resolver-rolebindings
|
||||||
namespace: user1
|
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-restricted-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: Role
|
kind: Role
|
||||||
|
@ -3,7 +3,6 @@ kind: Role
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-runner-role
|
name: mizu-runner-role
|
||||||
namespace: user1
|
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["pods"]
|
resources: ["pods"]
|
||||||
@ -20,15 +19,17 @@ rules:
|
|||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["configmaps"]
|
resources: ["configmaps"]
|
||||||
verbs: ["create", "delete"]
|
verbs: ["create", "delete"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods/log"]
|
||||||
|
verbs: ["get"]
|
||||||
---
|
---
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-runner-rolebindings
|
name: mizu-runner-rolebindings
|
||||||
namespace: user1
|
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-restricted-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: Role
|
kind: Role
|
||||||
|
Loading…
Reference in New Issue
Block a user