1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 18:38:40 +00:00

Merge pull request #135 from nirmata/21_enhancement

update namespace trigger + update documentation
This commit is contained in:
shuting 2019-06-03 16:32:20 -07:00 committed by GitHub
commit 1dcdb0033c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 118 additions and 104 deletions

View file

@ -98,12 +98,14 @@ spec:
selector:
matchExpressions:
- {key: kafka, operator: Exists}
generate:
generate:
kind: ConfigMap
name: zk-kafka-address
data:
ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
kind: ConfigMap
data:
ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
````
### 4. More examples

View file

@ -102,14 +102,11 @@ spec:
required:
- kind
- name
- namespace
properties:
kind:
type: string
name:
type: string
namespace:
type: string
clone:
type: object
required:

View file

@ -2,47 +2,82 @@
# Generate Configurations
```generatate``` feature can be applied to created namespaces to create new resources in them. This feature is useful when every namespace in a cluster must contain some basic required resources. The feature is available for policy rules in which the resource kind is Namespace.
```generate``` feature can be applied to created namespaces to create new resources in them. This feature is useful when every namespace in a cluster must contain some basic required resources. The feature is available for policy rules in which the resource kind is Namespace.
## Example
## Example 1
````yaml
apiVersion : kyverno.io/v1alpha1
kind : Policy
metadata :
name : basic-policy
spec :
apiVersion: kyverno.io/v1alpha1
kind: Policy
metadata:
name: basic-policy
spec:
rules:
- name: "Basic confog generator for all namespaces"
- name: "Basic config generator for all namespaces"
resource:
kind: Namespace
kinds:
- Namespace
selector:
matchLabels:
LabelForSelector : "namespace2"
generate:
# For now the next kinds are supported:
# ConfigMap
# Secret
- kind: ConfigMap
kind: ConfigMap
name: default-config
copyFrom:
clone:
namespace: default
name: config-template
data:
DB_ENDPOINT: mongodb://mydomain.ua/db_stage:27017
labels:
purpose: mongo
- kind: Secret
- name: "Basic config generator for all namespaces"
resource:
kinds:
- Namespace
selector:
matchLabels:
LabelForSelector : "namespace2"
generate:
kind: Secret
name: mongo-creds
data:
DB_USER: YWJyYWthZGFicmE=
DB_PASSWORD: YXBwc3dvcmQ=
labels:
purpose: mongo
data:
DB_USER: YWJyYWthZGFicmE=
DB_PASSWORD: YXBwc3dvcmQ=
metadata:
labels:
purpose: mongo
````
In this example, when this policy is applied, any new namespace will receive 2 new resources after its creation:
* ConfigMap copied from default/config-template with added value DB_ENDPOINT.
* Secret with values DB_USER and DB_PASSWORD.
In this example, when this policy is applied, any new namespace that satisfies the label selector will receive 2 new resources after its creation:
* ConfigMap copied from default/config-template.
* Secret with values DB_USER and DB_PASSWORD, and label ```purpose: mongo```.
Both resources will contain a label ```purpose: mongo```
## Example 2
````yaml
apiVersion: kyverno.io/v1alpha1
kind: Policy
metadata:
name: "default"
spec:
rules:
- name: "deny-all-traffic"
resource:
kinds:
- Namespace
name: "*"
generate:
kind: NetworkPolicy
name: deny-all-traffic
data:
spec:
podSelector:
matchLabels: {}
matchExpressions: []
policyTypes: []
metadata:
annotations: {}
labels:
policyname: "default"
````
In this example, when this policy is applied, any new namespace will receive a new NetworkPolicy resource based on the specified template that by default denies all inbound and outbound traffic.
---
<small>*Read Next >> [Testing Policies](/documentation/testing-policies.md)*</small>

View file

@ -14,21 +14,21 @@ spec:
generate :
kind: ConfigMap
name : copied-cm
copyFrom :
clone:
namespace : default
name : game-config
data :
secretData: "data from cmg"
- name: "zk-kafka-address"
resource:
resource:
kinds:
- Namespace
- Namespace
selector:
matchExpressions:
matchExpressions:
- {key: LabelForSelector, operator: In, values: [namespace2]}
generate:
generate:
kind: ConfigMap
name: zk-kafka-address
data:
ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
kind: ConfigMap
data:
ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"

View file

@ -0,0 +1,24 @@
apiVersion: kyverno.io/v1alpha1
kind: Policy
metadata:
name: "default"
spec:
rules:
- name: "deny-all-traffic"
resource:
kinds:
- Namespace
name: "*"
generate:
kind: NetworkPolicy
name: deny-all-traffic
data:
spec:
podSelector:
matchLabels: {}
matchExpressions: []
policyTypes: []
metadata:
annotations: {}
labels:
policyname: "default"

View file

@ -61,11 +61,10 @@ type Validation struct {
// Generation describes which resources will be created when other resource is created
type Generation struct {
Kind string `json:"kind"`
Name string `json:"name"`
Namespace string `json:"namespace"`
Data interface{} `json:"data"`
Clone *CloneFrom `json:"clone"`
Kind string `json:"kind"`
Name string `json:"name"`
Data interface{} `json:"data"`
Clone *CloneFrom `json:"clone"`
}
// CloneFrom - location of a Secret or a ConfigMap

View file

@ -1,7 +1,6 @@
package client
import (
"errors"
"fmt"
"strings"
"time"
@ -166,41 +165,7 @@ func ConvertToRuntimeObject(obj *unstructured.Unstructured) (*runtime.Object, er
return &runtimeObj, nil
}
// only support 2 levels of keys
// To-Do support multiple levels of key
func keysExist(data map[string]interface{}, keys ...string) bool {
var v interface{}
var t map[string]interface{}
var ok bool
for _, key := range keys {
ks := strings.Split(key, ".")
if len(ks) > 2 {
glog.Error("Only support 2 levels of keys from root. Support to be extendend in future")
return false
}
if v, ok = data[ks[0]]; !ok {
glog.Infof("key %s does not exist", key)
return false
}
if len(ks) == 2 {
if t, ok = v.(map[string]interface{}); !ok {
glog.Error("expecting type map[string]interface{}")
}
return keyExist(t, ks[1])
}
}
return true
}
func keyExist(data map[string]interface{}, key string) (ok bool) {
if _, ok = data[key]; !ok {
glog.Infof("key %s does not exist", key)
}
return ok
}
// support mode 'data' -> create resource
// To-Do: support 'from' -> copy/clone the resource
// GenerateResource creates resource of the specified kind(supports 'clone' & 'data')
func (c *Client) GenerateResource(generator types.Generation, namespace string) error {
var err error
rGVR := c.getGVRFromKind(generator.Kind)
@ -214,10 +179,6 @@ func (c *Client) GenerateResource(generator types.Generation, namespace string)
utilruntime.HandleError(err)
return err
}
// verify if mandatory attributes have been defined
if !keysExist(rdata, "kind", "apiVersion", "metadata.name", "metadata.namespace") {
return errors.New("mandatory keys not defined")
}
}
// clone -> copy from existing resource
if generator.Clone != nil {
@ -230,7 +191,7 @@ func (c *Client) GenerateResource(generator types.Generation, namespace string)
resource.SetUnstructuredContent(rdata)
resource.SetName(generator.Name)
resource.SetNamespace(generator.Namespace)
resource.SetNamespace(namespace)
resource.SetResourceVersion("")
err = c.waitUntilNamespaceIsCreated(namespace)
@ -238,7 +199,7 @@ func (c *Client) GenerateResource(generator types.Generation, namespace string)
glog.Errorf("Can't create a resource %s: %v", generator.Name, err)
return nil
}
_, err = c.CreateResource(rGVR.Resource, generator.Namespace, resource)
_, err = c.CreateResource(rGVR.Resource, namespace, resource)
if err != nil {
return err
}

View file

@ -46,6 +46,6 @@ func applyRuleGenerator(client *client.Client, rawResource []byte, generator *ku
if err != nil {
return fmt.Errorf("Unable to apply generator for %s '%s/%s' : %v", generator.Kind, namespace, generator.Name, err)
}
glog.Infof("Successfully applied generator %s/%s", generator.Kind, generator.Name)
glog.Infof("Successfully applied generator %s '%s/%s'", generator.Kind, namespace, generator.Name)
return nil
}

View file

@ -14,8 +14,6 @@ spec:
generate :
kind: ConfigMap
name : copied-cm
copyFrom :
clone:
namespace : default
name : game-config
data :
secretData: "data from cmg"
name : game-config

View file

@ -32,11 +32,9 @@ spec :
generate :
kind: ConfigMap
name : copied-cm
copyFrom :
clone:
namespace : default
name : game-config
data :
secretData: "data from cmg"
- name: "generateCM"
resource :
@ -49,13 +47,13 @@ spec :
kind: ConfigMap
name : generated-cm
data :
secretData: "very sensitive data from cmg"
database: mongodb
database_uri: mongodb://localhost:27017
keys: |
image.public.key=771
rsa.public.key=42
data:
secretData: "very sensitive data from cmg"
database: mongodb
database_uri: mongodb://localhost:27017
keys: |
image.public.key=771
rsa.public.key=42
- name: "generateSecret"
resource :