1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00

Merge branch 'main' into policyreport

# Conflicts:
#	pkg/utils/util.go
This commit is contained in:
Shuting Zhao 2020-11-03 16:43:00 -08:00
commit a1eda94a80
9 changed files with 114 additions and 63 deletions

View file

@ -2,10 +2,10 @@ name: build
on:
push:
branches:
- 'master'
- 'main'
pull_request:
branches:
- 'master'
- 'main'
jobs:
releaser:

View file

@ -2,7 +2,7 @@ name: image
on:
push:
branches:
- 'master'
- 'main'
jobs:
push-images:
runs-on: ubuntu-latest

View file

@ -2,10 +2,10 @@ name: test
on:
push:
branches:
- master
- main
pull_request:
branches:
- master
- main
jobs:

View file

@ -1,20 +1,22 @@
# kyverno
# Kyverno
[Kyverno](https://kyverno.io) is a Kubernetes Native Policy Management engine. It allows you to
[Kyverno](https://kyverno.io) is a Kubernetes Native Policy Management engine. It allows you to:
* Manage policies as Kubernetes resources.
* Validate, mutate, and generate configurations for any resource.
* Manage policies as Kubernetes resources (no new language required.)
* Validate, mutate, and generate resource configurations.
* Select resources based on labels and wildcards.
* View policy enforcement as events.
* Detect policy violations for existing resources.
* Scan existing resources for violations.
Access the complete user documentation and guides at: https://kyverno.io.
## TL;DR;
```console
## Add the nirmata Helm repository
## Add the Kyverno Helm repository
$ helm repo add kyverno https://nirmata.github.io/kyverno
## Install the kyverno helm chart
## Install the Kyverno Helm chart
$ helm install kyverno --namespace kyverno kyverno/kyverno
```
@ -24,19 +26,27 @@ This chart bootstraps a Kyverno deployment on a [Kubernetes](http://kubernetes.i
## Installing the Chart
Kyverno makes assumptions about naming of namespaces and resources. Therefore, the chart must be installed with the default release name `kyverno` (default if --name is omitted) and in the namespace 'kyverno':
**Add the Kyverno Helm repository:**
```console
$ helm repo add kyverno https://nirmata.github.io/kyverno
```
**Create a namespace:**
You can install Kyverno in any namespace. The examples use `kyverno` as the namespace.
```console
$ kubectl create namespace kyverno
```
**Install the Kyverno chart:**
```console
$ helm install kyverno --namespace kyverno kyverno ./charts/kyverno
```
Note that Helm by default expects the namespace to already exist before running helm install. Create the namespace using:
```console
$ kubectl create ns kyverno
```
The command deploys Kyverno on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
The command deploys Kyverno on the Kubernetes cluster with default configuration. The [installation](https://kyverno.io/docs/installation/) guide lists the parameters that can be configured during installation.
## Uninstalling the Chart
@ -110,4 +120,8 @@ $ helm install --namespace kyverno kyverno ./charts/kyverno -f values.yaml
If `createSelfSignedCert` is `true`, Helm will take care of the steps of creating an external self-signed certificate describe in option 2 of the [installation documentation](https://github.com/kyverno/kyverno/blob/master/documentation/installation.md#option-2-use-your-own-ca-signed-certificate)
If `createSelfSignedCert` is `false`, Kyverno will generate a pair using the kube-controller-manager., or you can provide your own TLS CA and signed-key pair and create the secret yourself as described in the documentation.
If `createSelfSignedCert` is `false`, Kyverno will generate a self-signed CA and a certificate, or you can provide your own TLS CA and signed-key pair and create the secret yourself as described in the documentation.
## Kyverno CLI
See: https://kyverno.io/docs/kyverno-cli/

View file

@ -65,9 +65,7 @@ func main() {
}
// Exit for unsupported version of kubernetes cluster
// https://github.com/kyverno/kyverno/issues/700
// - supported from v1.12.7+
if !utils.HigherThanKubernetesVersion(client, log.Log, 1, 12, 7) {
if !utils.HigherThanKubernetesVersion(client, log.Log, 1, 14, 0) {
os.Exit(1)
}

View file

@ -4,6 +4,7 @@ import (
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/context"
"strings"
)
//OperatorHandler provides interface to manage types
@ -21,21 +22,30 @@ type VariableSubstitutionHandler = func(log logr.Logger, ctx context.EvalInterfa
//CreateOperatorHandler returns the operator handler based on the operator used in condition
func CreateOperatorHandler(log logr.Logger, ctx context.EvalInterface, op kyverno.ConditionOperator, subHandler VariableSubstitutionHandler) OperatorHandler {
switch op {
case kyverno.Equal:
str := strings.ToLower(string(op))
switch str {
case strings.ToLower(string(kyverno.Equal)):
return NewEqualHandler(log, ctx, subHandler)
case kyverno.NotEqual:
return NewNotEqualHandler(log, ctx, subHandler)
case kyverno.Equals:
case strings.ToLower(string(kyverno.Equals)):
return NewEqualHandler(log, ctx, subHandler)
case kyverno.NotEquals:
case strings.ToLower(string(kyverno.NotEqual)):
return NewNotEqualHandler(log, ctx, subHandler)
case kyverno.In:
case strings.ToLower(string(kyverno.NotEquals)):
return NewNotEqualHandler(log, ctx, subHandler)
case strings.ToLower(string(kyverno.In)):
return NewInHandler(log, ctx, subHandler)
case kyverno.NotIn:
case strings.ToLower(string(kyverno.NotIn)):
return NewNotInHandler(log, ctx, subHandler)
default:
log.Info("operator not supported", "operator", string(op))
log.Info("operator not supported", "operator", str)
}
return nil
}

View file

@ -18,6 +18,8 @@ import (
"k8s.io/client-go/rest"
)
var regexVersion = regexp.MustCompile(`v(\d+).(\d+).(\d+)\.*`)
//Contains Check if strint is contained in a list of string
func contains(list []string, element string, fn func(string, string) bool) bool {
for _, e := range list {
@ -55,14 +57,6 @@ func NewKubeClient(config *rest.Config) (kubernetes.Interface, error) {
return kclient, nil
}
//Btoi converts boolean to int
func Btoi(b bool) int {
if b {
return 1
}
return 0
}
//CRDInstalled to check if the CRD is installed or not
func CRDInstalled(discovery client.IDiscovery, log logr.Logger) bool {
logger := log.WithName("CRDInstalled")
@ -128,41 +122,50 @@ func ConvertResource(raw []byte, group, version, kind, namespace string) (unstru
return *obj, nil
}
// HigherThanKubernetesVersion compare kuberneates client version to user given version
func HigherThanKubernetesVersion(client *client.Client, log logr.Logger, k8smajor, k8sminor, k8ssub int) bool {
// HigherThanKubernetesVersion compare Kubernetes client version to user given version
func HigherThanKubernetesVersion(client *client.Client, log logr.Logger, major, minor, patch int) bool {
logger := log.WithName("CompareKubernetesVersion")
serverVersion, err := client.DiscoveryClient.GetServerVersion()
if err != nil {
logger.Error(err, "Failed to get kubernetes server version")
return false
}
exp := regexp.MustCompile(`v(\d*).(\d*).(\d*)`)
groups := exp.FindAllStringSubmatch(serverVersion.String(), -1)
b, err := isVersionHigher(serverVersion.String(), major, minor, patch)
if err != nil {
logger.Error(err, "serverVersion", serverVersion)
return false
}
return b
}
func isVersionHigher(version string, major int, minor int, patch int) (bool, error) {
groups := regexVersion.FindAllStringSubmatch(version, -1)
if len(groups) != 1 || len(groups[0]) != 4 {
logger.Error(err, "Failed to extract kubernetes server version", "serverVersion", serverVersion)
return false
return false, fmt.Errorf("invalid version %s. Expected {major}.{minor}.{patch}", version)
}
// convert string to int
// assuming the version are always intergers
major, err := strconv.Atoi(groups[0][1])
currentMajor, err := strconv.Atoi(groups[0][1])
if err != nil {
logger.Error(err, "Failed to extract kubernetes major server version", "serverVersion", serverVersion)
return false
return false, fmt.Errorf("failed to extract major version from %s", version)
}
minor, err := strconv.Atoi(groups[0][2])
currentMinor, err := strconv.Atoi(groups[0][2])
if err != nil {
logger.Error(err, "Failed to extract kubernetes minor server version", "serverVersion", serverVersion)
return false
return false, fmt.Errorf("failed to extract minor version from %s", version)
}
sub, err := strconv.Atoi(groups[0][3])
currentPatch, err := strconv.Atoi(groups[0][3])
if err != nil {
logger.Error(err, "Failed to extract kubernetes sub minor server version", "serverVersion", serverVersion)
return false
return false, fmt.Errorf("failed to extract minor version from %s", version)
}
if major <= k8smajor && minor <= k8sminor && sub < k8ssub {
return false
if currentMajor <= major && currentMinor <= minor && currentPatch <= patch {
return false, nil
}
return true
return true, nil
}
func SliceContains(slice []string, values ...string) bool {

View file

@ -65,5 +65,31 @@ func Test_containsNs(t *testing.T) {
patterns = []string{}
res = ContainsNamepace(patterns, "test")
assert.Assert(t, res == false)
}
func Test_higherVersion(t *testing.T) {
v, err := isVersionHigher("invalid.version", 1, 1, 1)
assert.Assert(t, v == false && err != nil)
v, err = isVersionHigher("invalid-version", 0, 0, 0)
assert.Assert(t, v == false && err != nil)
v, err = isVersionHigher("v1.1.1", 1, 1, 1)
assert.Assert(t, v == false && err == nil)
v, err = isVersionHigher("v1.0.0", 1, 1, 1)
assert.Assert(t, v == false && err == nil)
v, err = isVersionHigher("v1.5.9", 1, 5, 8)
assert.Assert(t, v == true && err == nil)
v, err = isVersionHigher("v1.5.9+distro", 1, 5, 8)
assert.Assert(t, v == true && err == nil)
v, err = isVersionHigher("v1.5.9+distro", 1, 5, 8)
assert.Assert(t, v == true && err == nil)
v, err = isVersionHigher("v1.5.9-rc2", 1, 5, 9)
assert.Assert(t, v == false && err == nil)
}

View file

@ -20,7 +20,7 @@ func (ws *WebhookServer) policyValidation(request *v1beta1.AdmissionRequest) *v1
//TODO: can this happen? wont this be picked by OpenAPI spec schema ?
if err := policyvalidate.Validate(request.Object.Raw, ws.client, false, ws.openAPIController); err != nil {
logger.Error(err, "faield to validate policy")
logger.Error(err, "failed to validate policy")
return &v1beta1.AdmissionResponse{
Allowed: false,
Result: &metav1.Status{