mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 18:38:40 +00:00
update namespace trigger + update documentation
This commit is contained in:
parent
f5d9b039ec
commit
ecca97b2a0
8 changed files with 108 additions and 90 deletions
|
@ -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
|
||||
|
|
|
@ -102,14 +102,11 @@ spec:
|
|||
required:
|
||||
- kind
|
||||
- name
|
||||
- namespace
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
clone:
|
||||
type: object
|
||||
required:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
24
examples/generate/policy_networkPolicy.yaml
Normal file
24
examples/generate/policy_networkPolicy.yaml
Normal 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"
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue