Add readonly ServiceAccount in Sonobuoy chart

Using this readonly ServiceAccount enables plugins
to use a Kubernetes client with different permissions
than the Sonobuoy ServiceAccount, which has full
permissions on the cluster.

This ServiceAccount enables get/list/watch on all resource types in all
API groups.

The reason the secret is used to mount the service account token because
there is not a way to specify a service account from just a container
spec [1]. Sonobuoy doesn't provide access to the pod spec for plugins,
so we are limited to the container spec.

[1] https://github.com/kubernetes/kubernetes/issues/66020

Change-Id: I69aeaaedf1fb7672f7167c83b220cf6abb890cb5
This commit is contained in:
Dustin Specker 2018-10-19 12:13:14 -05:00
parent 239471b1a8
commit 1765e62acb
2 changed files with 109 additions and 0 deletions

View File

@ -0,0 +1,108 @@
{{/*
Copyright 2019 The Openstack-Helm 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/}}
{{/*
Enabling this manifest enables the usage of a ServiceAccount with
readonly permissions for Sonobuoy plugins that mount the created
token.
To use this readonly ServiceAccount mount the ServiceAccountToken in
`values.yaml` like:
```
conf:
plugins:
- name: plugin-needing-readonly.yaml
data: |
sonobuoy-config:
driver: Job
plugin-name: plugin-needing-readonly
result-type: plugin-needing-readonly
spec:
name: plugin-needing-readonly
image: "plugin-needing-readonly:latest"
imagePullPolicy: "IfNotPresent"
volumeMounts:
- mountPath: /tmp/results
name: results
readOnly: false
- name: readonly-token
# It's recommended to use this mountPath to overwrite the
# Sonobuoy service account credentials that are mounted
# by default in the plugin containers to prevent plugins
# from accidentally using credentials with full permissions.
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
extra-volumes:
- name: readonly-token
secret:
secretName: sonobuoy-readonly-serviceaccount-token-secret
```
After mounting the readonly token, the example at
https://github.com/kubernetes-client/python/tree/3fb2be14e18d84edef094bbd908b6bb3e39aafe6#example
may be referenced to list pods, etc.
*/}}
{{- if .Values.manifests.serviceaccount_readonly }}
{{- $envAll := . }}
{{- $serviceAccountName := "sonobuoy-readonly-serviceaccount" }}
{{ tuple $envAll "sonobuoy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: sonobuoy-readonly-clusterrole
rules:
- apiGroups:
- "*"
resources:
- "*"
verbs:
- "get"
- "list"
- "watch"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sonobuoy-readonly-clusterrolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: sonobuoy-readonly-clusterrole
subjects:
- kind: ServiceAccount
name: {{ $serviceAccountName }}
namespace: {{ .Release.Namespace }}
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: {{ $serviceAccountName }}-token-secret
namespace: {{ .Release.Namespace }}
annotations:
kubernetes.io/service-account.name: {{ $serviceAccountName }}
{{/*
post-install hook is required to cause ServiceAccount to be deployed
before creating a secret token for it. By default helm deploys secrets
before ServiceAccounts which causes this secret to not exist since the
ServiceAccount is missing.
*/}}
"helm.sh/hook": "post-install"
---
{{- end }}

View File

@ -97,6 +97,7 @@ manifests:
pod_api: true pod_api: true
secret_etc: true secret_etc: true
secret_keystone: true secret_keystone: true
serviceaccount_readonly: false
conf: conf:
publish_results: true publish_results: true