mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 18:38:40 +00:00
feat: add exclude roles/cluster roles support in configmap (#6779)
* feat: add exclude roles/cluster roles support in configmap Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * update chart Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * filter handler Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
80fc3013d3
commit
298e250693
10 changed files with 87 additions and 22 deletions
|
@ -8,6 +8,7 @@
|
|||
- Refactored `kyverno` chart, migration instructions are available in chart `README.md`.
|
||||
- Image references in the json context are not mutated to canonical form anymore, do not assume a registry domain is always present.
|
||||
- Added support for configuring webhook annotations in the config map through `webhookAnnotations` stanza.
|
||||
- Added `excludeRoles` and `excludeClusterRoles` support in configuration.
|
||||
|
||||
## v1.9.0-rc.1
|
||||
|
||||
|
|
|
@ -40,3 +40,5 @@ annotations:
|
|||
description: allow overriding PDB api version
|
||||
- kind: fixed
|
||||
description: missing image pull secrets in helm hooks
|
||||
- kind: added
|
||||
description: support `excludeRoles` and `excludeClusterRoles` in config
|
||||
|
|
|
@ -174,6 +174,8 @@ In `v3` chart values changed significantly, please read the instructions below t
|
|||
- Image references are now using the `registry` setting, if you override the registry or repository fields please use `registry` (`--set image.registry=ghcr.io --set image.repository=kyverno/kyverno` instead of `--set image.repository=ghcr.io/kyverno/kyverno`).
|
||||
|
||||
- Admission controller `Deployment` name changed from `kyverno` to `kyverno-admission-controller`.
|
||||
- `config.excludeUsername` was renamed to `config.excludeUsernames`
|
||||
- `config.excludeGroupRole` was renamed to `config.excludeGroups`
|
||||
|
||||
## Uninstalling the Chart
|
||||
|
||||
|
@ -200,8 +202,8 @@ The command removes all the Kubernetes components associated with the chart and
|
|||
| config.annotations | object | `{}` | Additional annotations to add to the configmap. |
|
||||
| config.enableDefaultRegistryMutation | bool | `true` | Enable registry mutation for container images. Enabled by default. |
|
||||
| config.defaultRegistry | string | `"docker.io"` | The registry hostname used for the image mutation. |
|
||||
| config.excludeGroupRole | list | `[]` | Exclude group role |
|
||||
| config.excludeUsername | list | `[]` | Exclude username |
|
||||
| config.excludeGroups | list | `[]` | Exclude groups |
|
||||
| config.excludeUsernames | list | `[]` | Exclude usernames |
|
||||
| config.excludeBackgroundUsernames | list | `[]` | Exclude usernames for mutateExisting and generate policies |
|
||||
| config.generateSuccessEvents | bool | `false` | Generate success events. |
|
||||
| config.resourceFilters | list | See [values.yaml](values.yaml) | Resource types to be skipped by the Kyverno policy engine. Make sure to surround each entry in quotes so that it doesn't get parsed as a nested YAML list. These are joined together without spaces, run through `tpl`, and the result is set in the config map. |
|
||||
|
|
|
@ -174,6 +174,8 @@ In `v3` chart values changed significantly, please read the instructions below t
|
|||
- Image references are now using the `registry` setting, if you override the registry or repository fields please use `registry` (`--set image.registry=ghcr.io --set image.repository=kyverno/kyverno` instead of `--set image.repository=ghcr.io/kyverno/kyverno`).
|
||||
|
||||
- Admission controller `Deployment` name changed from `kyverno` to `kyverno-admission-controller`.
|
||||
- `config.excludeUsername` was renamed to `config.excludeUsernames`
|
||||
- `config.excludeGroupRole` was renamed to `config.excludeGroups`
|
||||
|
||||
## Uninstalling the Chart
|
||||
|
||||
|
|
|
@ -16,8 +16,17 @@ data:
|
|||
defaultRegistry: {{ . | quote }}
|
||||
{{- end }}
|
||||
generateSuccessEvents: {{ .Values.config.generateSuccessEvents | quote }}
|
||||
{{- with .Values.config.excludeGroupRole }}
|
||||
excludeGroupRole: {{ join "," . | quote }}
|
||||
{{- with .Values.config.excludeGroups }}
|
||||
excludeGroups: {{ join "," . | quote }}
|
||||
{{- end -}}
|
||||
{{- with .Values.config.excludeUsernames }}
|
||||
excludeUsernames: {{ join "," . | quote }}
|
||||
{{- end -}}
|
||||
{{- with .Values.config.excludeRoles }}
|
||||
excludeRoles: {{ join "," . | quote }}
|
||||
{{- end -}}
|
||||
{{- with .Values.config.excludeClusterRoles }}
|
||||
excludeClusterRoles: {{ join "," . | quote }}
|
||||
{{- end -}}
|
||||
{{- $backgroundUsernames := (printf "system:serviceaccount:%s:%s" (include "kyverno.namespace" .) (include "kyverno.background-controller.serviceAccountName" .)) }}
|
||||
{{- if .Values.config.excludeBackgroundUsernames }}
|
||||
|
@ -26,9 +35,6 @@ data:
|
|||
{{- else }}
|
||||
excludeBackgroundUsernames: {{ $backgroundUsernames }}
|
||||
{{- end -}}
|
||||
{{- with .Values.config.excludeUsername }}
|
||||
excludeUsername: {{ join "," . | quote }}
|
||||
{{- end -}}
|
||||
{{- if .Values.config.resourceFilters }}
|
||||
resourceFilters: {{ include "kyverno.config.resourceFilters" . | quote }}
|
||||
{{- end -}}
|
||||
|
|
|
@ -49,11 +49,11 @@ config:
|
|||
# -- The registry hostname used for the image mutation.
|
||||
defaultRegistry: docker.io
|
||||
|
||||
# -- Exclude group role
|
||||
excludeGroupRole: []
|
||||
# -- Exclude groups
|
||||
excludeGroups: []
|
||||
|
||||
# -- Exclude username
|
||||
excludeUsername: []
|
||||
# -- Exclude usernames
|
||||
excludeUsernames: []
|
||||
|
||||
# -- Exclude usernames for mutateExisting and generate policies
|
||||
excludeBackgroundUsernames: []
|
||||
|
|
|
@ -139,10 +139,14 @@ type Configuration interface {
|
|||
GetEnableDefaultRegistryMutation() bool
|
||||
// ToFilter checks if the given resource is set to be filtered in the configuration
|
||||
ToFilter(kind, namespace, name string) bool
|
||||
// GetExcludedGroups return exclude groups
|
||||
// GetExcludedGroups return excluded groups
|
||||
GetExcludedGroups() []string
|
||||
// GetExcludedUsernames return exclude usernames
|
||||
// GetExcludedUsernames return excluded usernames
|
||||
GetExcludedUsernames() []string
|
||||
// GetExcludedRoles return excluded roles
|
||||
GetExcludedRoles() []string
|
||||
// GetExcludedClusterRoles return excluded roles
|
||||
GetExcludedClusterRoles() []string
|
||||
// GetExcludedBackgroundUsernames return exclude usernames for mutateExisting and generate policies
|
||||
GetExcludedBackgroundUsernames() []string
|
||||
// GetGenerateSuccessEvents return if should generate success events
|
||||
|
@ -161,6 +165,8 @@ type configuration struct {
|
|||
enableDefaultRegistryMutation bool
|
||||
excludedGroups []string
|
||||
excludedUsernames []string
|
||||
excludedRoles []string
|
||||
excludedClusterRoles []string
|
||||
excludeBackgroundUsernames []string
|
||||
filters []filter
|
||||
generateSuccessEvents bool
|
||||
|
@ -227,6 +233,18 @@ func (cd *configuration) GetExcludedUsernames() []string {
|
|||
return cd.excludedUsernames
|
||||
}
|
||||
|
||||
func (cd *configuration) GetExcludedRoles() []string {
|
||||
cd.mux.RLock()
|
||||
defer cd.mux.RUnlock()
|
||||
return cd.excludedRoles
|
||||
}
|
||||
|
||||
func (cd *configuration) GetExcludedClusterRoles() []string {
|
||||
cd.mux.RLock()
|
||||
defer cd.mux.RUnlock()
|
||||
return cd.excludedClusterRoles
|
||||
}
|
||||
|
||||
func (cd *configuration) GetExcludedBackgroundUsernames() []string {
|
||||
cd.mux.RLock()
|
||||
defer cd.mux.RUnlock()
|
||||
|
@ -276,6 +294,8 @@ func (cd *configuration) load(cm *corev1.ConfigMap) {
|
|||
cd.filters = []filter{}
|
||||
cd.excludedUsernames = []string{}
|
||||
cd.excludedGroups = []string{}
|
||||
cd.excludedRoles = []string{}
|
||||
cd.excludedClusterRoles = []string{}
|
||||
cd.generateSuccessEvents = false
|
||||
cd.webhooks = nil
|
||||
cd.excludedGroups = append(cd.excludedGroups, defaultExcludedGroups...)
|
||||
|
@ -305,25 +325,39 @@ func (cd *configuration) load(cm *corev1.ConfigMap) {
|
|||
cd.enableDefaultRegistryMutation = newEnableDefaultRegistryMutation
|
||||
}
|
||||
// load excludeGroupRole
|
||||
excludedGroups, ok := cm.Data["excludeGroupRole"]
|
||||
excludedGroups, ok := cm.Data["excludeGroups"]
|
||||
if !ok {
|
||||
logger.V(6).Info("configuration: No excludeGroupRole defined in ConfigMap")
|
||||
logger.V(6).Info("configuration: No excludeGroups defined in ConfigMap")
|
||||
} else {
|
||||
cd.excludedGroups = parseRbac(excludedGroups)
|
||||
cd.excludedGroups = parseStrings(excludedGroups)
|
||||
}
|
||||
// load excludeUsername
|
||||
excludedUsernames, ok := cm.Data["excludeUsername"]
|
||||
excludedUsernames, ok := cm.Data["excludeUsernames"]
|
||||
if !ok {
|
||||
logger.V(6).Info("configuration: No excludeUsername defined in ConfigMap")
|
||||
logger.V(6).Info("configuration: No excludeUsernames defined in ConfigMap")
|
||||
} else {
|
||||
cd.excludedUsernames = parseRbac(excludedUsernames)
|
||||
cd.excludedUsernames = parseStrings(excludedUsernames)
|
||||
}
|
||||
// load excludeRoles
|
||||
excludedRoles, ok := cm.Data["excludeRoles"]
|
||||
if !ok {
|
||||
logger.V(6).Info("configuration: No excludeRoles defined in ConfigMap")
|
||||
} else {
|
||||
cd.excludedRoles = parseStrings(excludedRoles)
|
||||
}
|
||||
// load excludeClusterRoles
|
||||
excludedClusterRoles, ok := cm.Data["excludeClusterRoles"]
|
||||
if !ok {
|
||||
logger.V(6).Info("configuration: No excludeClusterRoles defined in ConfigMap")
|
||||
} else {
|
||||
cd.excludedClusterRoles = parseStrings(excludedClusterRoles)
|
||||
}
|
||||
// load excludeBackgroundUsernames
|
||||
excludeBackgroundUsernames, ok := cm.Data["excludeBackgroundUsernames"]
|
||||
if !ok {
|
||||
logger.V(6).Info("configuration: No excludeBackgroundUsernames defined in ConfigMap")
|
||||
} else {
|
||||
cd.excludeBackgroundUsernames = parseRbac(excludeBackgroundUsernames)
|
||||
cd.excludeBackgroundUsernames = parseStrings(excludeBackgroundUsernames)
|
||||
}
|
||||
// load generateSuccessEvents
|
||||
generateSuccessEvents, ok := cm.Data["generateSuccessEvents"]
|
||||
|
@ -365,6 +399,8 @@ func (cd *configuration) unload() {
|
|||
cd.enableDefaultRegistryMutation = true
|
||||
cd.excludedUsernames = []string{}
|
||||
cd.excludedGroups = []string{}
|
||||
cd.excludedRoles = []string{}
|
||||
cd.excludedClusterRoles = []string{}
|
||||
cd.generateSuccessEvents = false
|
||||
cd.webhooks = nil
|
||||
cd.webhookAnnotations = nil
|
||||
|
|
|
@ -21,7 +21,7 @@ func parseWebhooks(in string) ([]WebhookConfig, error) {
|
|||
return webhookCfgs, nil
|
||||
}
|
||||
|
||||
func parseRbac(in string) []string {
|
||||
func parseStrings(in string) []string {
|
||||
var out []string
|
||||
for _, in := range strings.Split(in, ",") {
|
||||
in := strings.TrimSpace(in)
|
||||
|
|
|
@ -37,7 +37,7 @@ func Test_parseRbac(t *testing.T) {
|
|||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := parseRbac(tt.args.in); !reflect.DeepEqual(got, tt.want) {
|
||||
if got := parseStrings(tt.args.in); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("parseRbac() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -41,6 +41,22 @@ func (inner AdmissionHandler) withFilter(c config.Configuration) AdmissionHandle
|
|||
}
|
||||
}
|
||||
}
|
||||
// filter by roles
|
||||
for _, role := range c.GetExcludedRoles() {
|
||||
for _, candidate := range request.Roles {
|
||||
if wildcard.Match(role, candidate) {
|
||||
return admissionutils.ResponseSuccess(request.UID)
|
||||
}
|
||||
}
|
||||
}
|
||||
// filter by cluster roles
|
||||
for _, clusterRole := range c.GetExcludedClusterRoles() {
|
||||
for _, candidate := range request.ClusterRoles {
|
||||
if wildcard.Match(clusterRole, candidate) {
|
||||
return admissionutils.ResponseSuccess(request.UID)
|
||||
}
|
||||
}
|
||||
}
|
||||
// filter by resource filters
|
||||
if c.ToFilter(request.Kind.Kind, request.Namespace, request.Name) {
|
||||
return admissionutils.ResponseSuccess(request.UID)
|
||||
|
|
Loading…
Add table
Reference in a new issue