mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
feat: support exclude block in generating VAPs (#10215)
Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
parent
35494bd8bb
commit
b0cef72df1
48 changed files with 942 additions and 81 deletions
|
@ -14,7 +14,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildValidatingAdmissionPolicy is used to build a Kubernetes ValidatingAdmissionPolicy from a Kyverno policy
|
// BuildValidatingAdmissionPolicy is used to build a Kubernetes ValidatingAdmissionPolicy from a Kyverno policy
|
||||||
func BuildValidatingAdmissionPolicy(discoveryClient dclient.IDiscovery, vap *admissionregistrationv1alpha1.ValidatingAdmissionPolicy, cpol kyvernov1.PolicyInterface) error {
|
func BuildValidatingAdmissionPolicy(
|
||||||
|
discoveryClient dclient.IDiscovery,
|
||||||
|
vap *admissionregistrationv1alpha1.ValidatingAdmissionPolicy,
|
||||||
|
cpol kyvernov1.PolicyInterface,
|
||||||
|
) error {
|
||||||
// set owner reference
|
// set owner reference
|
||||||
vap.OwnerReferences = []metav1.OwnerReference{
|
vap.OwnerReferences = []metav1.OwnerReference{
|
||||||
{
|
{
|
||||||
|
@ -25,30 +29,51 @@ func BuildValidatingAdmissionPolicy(discoveryClient dclient.IDiscovery, vap *adm
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct validating admission policy resource rules
|
// construct the rules
|
||||||
var matchResources admissionregistrationv1alpha1.MatchResources
|
var matchResources admissionregistrationv1alpha1.MatchResources
|
||||||
var matchRules []admissionregistrationv1alpha1.NamedRuleWithOperations
|
var matchRules, excludeRules []admissionregistrationv1alpha1.NamedRuleWithOperations
|
||||||
|
|
||||||
rule := cpol.GetSpec().Rules[0]
|
rule := cpol.GetSpec().Rules[0]
|
||||||
|
|
||||||
|
// convert the match block
|
||||||
match := rule.MatchResources
|
match := rule.MatchResources
|
||||||
if !match.ResourceDescription.IsEmpty() {
|
if !match.ResourceDescription.IsEmpty() {
|
||||||
if err := translateResource(discoveryClient, &matchResources, &matchRules, match.ResourceDescription); err != nil {
|
if err := translateResource(discoveryClient, &matchResources, &matchRules, match.ResourceDescription, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if match.Any != nil {
|
if match.Any != nil {
|
||||||
if err := translateResourceFilters(discoveryClient, &matchResources, &matchRules, match.Any); err != nil {
|
if err := translateResourceFilters(discoveryClient, &matchResources, &matchRules, match.Any, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if match.All != nil {
|
if match.All != nil {
|
||||||
if err := translateResourceFilters(discoveryClient, &matchResources, &matchRules, match.All); err != nil {
|
if err := translateResourceFilters(discoveryClient, &matchResources, &matchRules, match.All, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set validating admission policy spec
|
// convert the exclude block
|
||||||
|
exclude := rule.ExcludeResources
|
||||||
|
if !exclude.ResourceDescription.IsEmpty() {
|
||||||
|
if err := translateResource(discoveryClient, &matchResources, &excludeRules, exclude.ResourceDescription, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if exclude.Any != nil {
|
||||||
|
if err := translateResourceFilters(discoveryClient, &matchResources, &excludeRules, exclude.Any, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if exclude.All != nil {
|
||||||
|
if err := translateResourceFilters(discoveryClient, &matchResources, &excludeRules, exclude.All, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set policy spec
|
||||||
vap.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{
|
vap.Spec = admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{
|
||||||
MatchConstraints: &matchResources,
|
MatchConstraints: &matchResources,
|
||||||
ParamKind: rule.Validation.CEL.ParamKind,
|
ParamKind: rule.Validation.CEL.ParamKind,
|
||||||
|
@ -64,7 +89,10 @@ func BuildValidatingAdmissionPolicy(discoveryClient dclient.IDiscovery, vap *adm
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildValidatingAdmissionPolicyBinding is used to build a Kubernetes ValidatingAdmissionPolicyBinding from a Kyverno policy
|
// BuildValidatingAdmissionPolicyBinding is used to build a Kubernetes ValidatingAdmissionPolicyBinding from a Kyverno policy
|
||||||
func BuildValidatingAdmissionPolicyBinding(vapbinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding, cpol kyvernov1.PolicyInterface) error {
|
func BuildValidatingAdmissionPolicyBinding(
|
||||||
|
vapbinding *admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding,
|
||||||
|
cpol kyvernov1.PolicyInterface,
|
||||||
|
) error {
|
||||||
// set owner reference
|
// set owner reference
|
||||||
vapbinding.OwnerReferences = []metav1.OwnerReference{
|
vapbinding.OwnerReferences = []metav1.OwnerReference{
|
||||||
{
|
{
|
||||||
|
@ -98,9 +126,14 @@ func BuildValidatingAdmissionPolicyBinding(vapbinding *admissionregistrationv1al
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateResourceFilters(discoveryClient dclient.IDiscovery, matchResources *admissionregistrationv1alpha1.MatchResources, rules *[]admissionregistrationv1alpha1.NamedRuleWithOperations, resFilters kyvernov1.ResourceFilters) error {
|
func translateResourceFilters(discoveryClient dclient.IDiscovery,
|
||||||
|
matchResources *admissionregistrationv1alpha1.MatchResources,
|
||||||
|
rules *[]admissionregistrationv1alpha1.NamedRuleWithOperations,
|
||||||
|
resFilters kyvernov1.ResourceFilters,
|
||||||
|
isMatch bool,
|
||||||
|
) error {
|
||||||
for _, filter := range resFilters {
|
for _, filter := range resFilters {
|
||||||
err := translateResource(discoveryClient, matchResources, rules, filter.ResourceDescription)
|
err := translateResource(discoveryClient, matchResources, rules, filter.ResourceDescription, isMatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -108,32 +141,47 @@ func translateResourceFilters(discoveryClient dclient.IDiscovery, matchResources
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateResource(discoveryClient dclient.IDiscovery, matchResources *admissionregistrationv1alpha1.MatchResources, rules *[]admissionregistrationv1alpha1.NamedRuleWithOperations, res kyvernov1.ResourceDescription) error {
|
func translateResource(
|
||||||
err := constructValidatingAdmissionPolicyRules(discoveryClient, rules, res)
|
discoveryClient dclient.IDiscovery,
|
||||||
|
matchResources *admissionregistrationv1alpha1.MatchResources,
|
||||||
|
rules *[]admissionregistrationv1alpha1.NamedRuleWithOperations,
|
||||||
|
res kyvernov1.ResourceDescription,
|
||||||
|
isMatch bool,
|
||||||
|
) error {
|
||||||
|
err := constructValidatingAdmissionPolicyRules(discoveryClient, rules, res, isMatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
matchResources.ResourceRules = *rules
|
if isMatch {
|
||||||
if len(res.Namespaces) > 0 {
|
matchResources.ResourceRules = *rules
|
||||||
namespaceSelector := &metav1.LabelSelector{
|
if len(res.Namespaces) > 0 {
|
||||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
namespaceSelector := &metav1.LabelSelector{
|
||||||
{
|
MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||||
Key: "kubernetes.io/metadata.name",
|
{
|
||||||
Operator: "In",
|
Key: "kubernetes.io/metadata.name",
|
||||||
Values: res.Namespaces,
|
Operator: "In",
|
||||||
|
Values: res.Namespaces,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
|
matchResources.NamespaceSelector = namespaceSelector
|
||||||
|
} else {
|
||||||
|
matchResources.NamespaceSelector = res.NamespaceSelector
|
||||||
}
|
}
|
||||||
matchResources.NamespaceSelector = namespaceSelector
|
matchResources.ObjectSelector = res.Selector
|
||||||
} else {
|
} else {
|
||||||
matchResources.NamespaceSelector = res.NamespaceSelector
|
matchResources.ExcludeResourceRules = *rules
|
||||||
}
|
}
|
||||||
matchResources.ObjectSelector = res.Selector
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func constructValidatingAdmissionPolicyRules(discoveryClient dclient.IDiscovery, rules *[]admissionregistrationv1alpha1.NamedRuleWithOperations, res kyvernov1.ResourceDescription) error {
|
func constructValidatingAdmissionPolicyRules(
|
||||||
|
discoveryClient dclient.IDiscovery,
|
||||||
|
rules *[]admissionregistrationv1alpha1.NamedRuleWithOperations,
|
||||||
|
res kyvernov1.ResourceDescription,
|
||||||
|
isMatch bool,
|
||||||
|
) error {
|
||||||
// translate operations to their corresponding values in validating admission policy.
|
// translate operations to their corresponding values in validating admission policy.
|
||||||
ops := translateOperations(res.GetOperations())
|
ops := translateOperations(res.GetOperations())
|
||||||
|
|
||||||
|
@ -191,6 +239,22 @@ func constructValidatingAdmissionPolicyRules(discoveryClient dclient.IDiscovery,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if exclude block has namespaces but no kinds, we need to add a rule for the namespaces
|
||||||
|
if !isMatch && len(res.Namespaces) > 0 && len(res.Kinds) == 0 {
|
||||||
|
r := admissionregistrationv1alpha1.NamedRuleWithOperations{
|
||||||
|
ResourceNames: res.Namespaces,
|
||||||
|
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||||
|
Rule: admissionregistrationv1.Rule{
|
||||||
|
Resources: []string{"namespaces"},
|
||||||
|
APIGroups: []string{""},
|
||||||
|
APIVersions: []string{"v1"},
|
||||||
|
},
|
||||||
|
Operations: ops,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
*rules = append(*rules, r)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +291,7 @@ func translateOperations(operations []string) []admissionregistrationv1.Operatio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default values for operations since it's a required field in validating admission policies
|
// set default values for operations since it's a required field in ValidatingAdmissionPolicies
|
||||||
if len(vapOperations) == 0 {
|
if len(vapOperations) == 0 {
|
||||||
vapOperations = append(vapOperations, admissionregistrationv1.Create)
|
vapOperations = append(vapOperations, admissionregistrationv1.Create)
|
||||||
vapOperations = append(vapOperations, admissionregistrationv1.Update)
|
vapOperations = append(vapOperations, admissionregistrationv1.Update)
|
||||||
|
|
|
@ -8,14 +8,12 @@ import (
|
||||||
// CanGenerateVAP check if Kyverno policy can be translated to a Kubernetes ValidatingAdmissionPolicy
|
// CanGenerateVAP check if Kyverno policy can be translated to a Kubernetes ValidatingAdmissionPolicy
|
||||||
func CanGenerateVAP(spec *kyvernov1.Spec) (bool, string) {
|
func CanGenerateVAP(spec *kyvernov1.Spec) (bool, string) {
|
||||||
var msg string
|
var msg string
|
||||||
if len(spec.Rules) > 1 {
|
if ok, msg := checkRuleCount(spec); !ok {
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: multiple rules are not applicable."
|
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
rule := spec.Rules[0]
|
rule := spec.Rules[0]
|
||||||
if !rule.HasValidateCEL() {
|
if ok, msg := checkRuleType(rule); !ok {
|
||||||
msg = "skip generating ValidatingAdmissionPolicy for non CEL rules."
|
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,65 +30,74 @@ func CanGenerateVAP(spec *kyvernov1.Spec) (bool, string) {
|
||||||
|
|
||||||
// check the matched/excluded resources of the CEL rule.
|
// check the matched/excluded resources of the CEL rule.
|
||||||
match, exclude := rule.MatchResources, rule.ExcludeResources
|
match, exclude := rule.MatchResources, rule.ExcludeResources
|
||||||
if !exclude.UserInfo.IsEmpty() || !exclude.ResourceDescription.IsEmpty() || exclude.All != nil || exclude.Any != nil {
|
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: Exclude is not applicable."
|
|
||||||
return false, msg
|
|
||||||
}
|
|
||||||
if ok, msg := checkUserInfo(match.UserInfo); !ok {
|
if ok, msg := checkUserInfo(match.UserInfo); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
if ok, msg := checkResources(match.ResourceDescription); !ok {
|
if ok, msg := checkUserInfo(exclude.UserInfo); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
if ok, msg := checkResources(match.ResourceDescription, true); !ok {
|
||||||
containsNamespaceSelector = false
|
return false, msg
|
||||||
containsObjectSelector = false
|
|
||||||
)
|
|
||||||
|
|
||||||
// since 'any' specify resources which will be ORed, it can be converted into multiple NamedRuleWithOperations in ValidatingAdmissionPolicy
|
|
||||||
for _, value := range match.Any {
|
|
||||||
if ok, msg := checkUserInfo(value.UserInfo); !ok {
|
|
||||||
return false, msg
|
|
||||||
}
|
|
||||||
if ok, msg := checkResources(value.ResourceDescription); !ok {
|
|
||||||
return false, msg
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.NamespaceSelector != nil {
|
|
||||||
containsNamespaceSelector = true
|
|
||||||
}
|
|
||||||
if value.Selector != nil {
|
|
||||||
containsObjectSelector = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// since namespace/object selectors are applied to all NamedRuleWithOperations in ValidatingAdmissionPolicy, then
|
if ok, msg := checkResources(exclude.ResourceDescription, false); !ok {
|
||||||
// we can't have more than one resource with namespace/object selectors.
|
|
||||||
if len(match.Any) > 1 && (containsNamespaceSelector || containsObjectSelector) {
|
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: NamespaceSelector / ObjectSelector across multiple resources are not applicable."
|
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// since 'all' specify resources which will be ANDed, we can't have more than one resource.
|
if ok, msg := checkResourceFilter(match.Any, true); !ok {
|
||||||
if match.All != nil {
|
return false, msg
|
||||||
if len(match.All) > 1 {
|
}
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' is not applicable."
|
|
||||||
return false, msg
|
if len(match.All) > 1 {
|
||||||
} else {
|
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the match block is not applicable."
|
||||||
if ok, msg := checkUserInfo(match.All[0].UserInfo); !ok {
|
return false, msg
|
||||||
return false, msg
|
}
|
||||||
}
|
if ok, msg := checkResourceFilter(match.All, true); !ok {
|
||||||
if ok, msg := checkResources(match.All[0].ResourceDescription); !ok {
|
return false, msg
|
||||||
return false, msg
|
}
|
||||||
}
|
|
||||||
}
|
if ok, msg := checkResourceFilter(exclude.Any, false); !ok {
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(exclude.All) > 1 {
|
||||||
|
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the exclude block is not applicable."
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
if ok, msg := checkResourceFilter(exclude.All, false); !ok {
|
||||||
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, msg
|
return true, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkResources(resource kyvernov1.ResourceDescription) (bool, string) {
|
func checkRuleCount(spec *kyvernov1.Spec) (bool, string) {
|
||||||
var msg string
|
var msg string
|
||||||
|
if len(spec.Rules) > 1 {
|
||||||
|
msg = "skip generating ValidatingAdmissionPolicy: multiple rules are not applicable."
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
return true, msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkRuleType(rule kyvernov1.Rule) (bool, string) {
|
||||||
|
var msg string
|
||||||
|
if !rule.HasValidateCEL() {
|
||||||
|
msg = "skip generating ValidatingAdmissionPolicy for non CEL rules."
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
return true, msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkResources(resource kyvernov1.ResourceDescription, isMatch bool) (bool, string) {
|
||||||
|
var msg string
|
||||||
|
if !isMatch {
|
||||||
|
if len(resource.Kinds) != 0 && len(resource.Namespaces) != 0 {
|
||||||
|
msg = "skip generating ValidatingAdmissionPolicy: excluding a resource within a namespace is not applicable."
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(resource.Annotations) != 0 {
|
if len(resource.Annotations) != 0 {
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: Annotations in resource description is not applicable."
|
msg = "skip generating ValidatingAdmissionPolicy: Annotations in resource description is not applicable."
|
||||||
return false, msg
|
return false, msg
|
||||||
|
@ -122,3 +129,38 @@ func checkUserInfo(info kyvernov1.UserInfo) (bool, string) {
|
||||||
}
|
}
|
||||||
return true, msg
|
return true, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkResourceFilter(resFilters kyvernov1.ResourceFilters, isMatch bool) (bool, string) {
|
||||||
|
var msg string
|
||||||
|
containsNamespaceSelector := false
|
||||||
|
containsObjectSelector := false
|
||||||
|
|
||||||
|
for _, value := range resFilters {
|
||||||
|
if ok, msg := checkUserInfo(value.UserInfo); !ok {
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
if ok, msg := checkResources(value.ResourceDescription, isMatch); !ok {
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.NamespaceSelector != nil {
|
||||||
|
containsNamespaceSelector = true
|
||||||
|
}
|
||||||
|
if value.Selector != nil {
|
||||||
|
containsObjectSelector = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isMatch {
|
||||||
|
if containsNamespaceSelector || containsObjectSelector {
|
||||||
|
msg = "skip generating ValidatingAdmissionPolicy: NamespaceSelector / ObjectSelector in the exclude block is not applicable."
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(resFilters) > 1 && (containsNamespaceSelector || containsObjectSelector) {
|
||||||
|
return false, "skip generating ValidatingAdmissionPolicy: NamespaceSelector / ObjectSelector across multiple resources in the match block are not applicable."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, msg
|
||||||
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ func Test_Check_Resources(t *testing.T) {
|
||||||
var res kyvernov1.ResourceDescription
|
var res kyvernov1.ResourceDescription
|
||||||
err := json.Unmarshal(test.resource, &res)
|
err := json.Unmarshal(test.resource, &res)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
out, _ := checkResources(res)
|
out, _ := checkResources(res, true)
|
||||||
assert.Equal(t, out, test.expected)
|
assert.Equal(t, out, test.expected)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-any-exclude-namespace-match-resource
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t16
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
apiVersion: kyverno.io/v1
|
apiVersion: kyverno.io/v1
|
||||||
kind: ClusterPolicy
|
kind: ClusterPolicy
|
||||||
metadata:
|
metadata:
|
||||||
name: disallow-host-path-t10
|
name: disallow-host-path-t16
|
||||||
spec:
|
spec:
|
||||||
validationFailureAction: Audit
|
validationFailureAction: Audit
|
||||||
background: false
|
background: false
|
||||||
|
@ -17,8 +17,10 @@ spec:
|
||||||
- UPDATE
|
- UPDATE
|
||||||
exclude:
|
exclude:
|
||||||
any:
|
any:
|
||||||
- clusterRoles:
|
- resources:
|
||||||
- cluster-admin
|
namespaces:
|
||||||
|
- testing-ns
|
||||||
|
- staging-ns
|
||||||
validate:
|
validate:
|
||||||
cel:
|
cel:
|
||||||
expressions:
|
expressions:
|
|
@ -0,0 +1,41 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t16
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t16
|
||||||
|
spec:
|
||||||
|
failurePolicy: Fail
|
||||||
|
matchConstraints:
|
||||||
|
excludeResourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resourceNames:
|
||||||
|
- testing-ns
|
||||||
|
- staging-ns
|
||||||
|
resources:
|
||||||
|
- namespaces
|
||||||
|
resourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
validations:
|
||||||
|
- expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume,
|
||||||
|
!has(volume.hostPath))'
|
||||||
|
message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath
|
||||||
|
must be unset.
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t16-binding
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t16
|
||||||
|
spec:
|
||||||
|
policyName: disallow-host-path-t16
|
||||||
|
validationActions:
|
||||||
|
- Audit
|
||||||
|
- Warn
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-any-exclude-resource-match-with-namespace-selector
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t14
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t14
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: host-path
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: critical
|
||||||
|
exclude:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
names:
|
||||||
|
- "testing"
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||||
|
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."
|
|
@ -0,0 +1,43 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t14
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t14
|
||||||
|
spec:
|
||||||
|
failurePolicy: Fail
|
||||||
|
matchConstraints:
|
||||||
|
excludeResourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resourceNames:
|
||||||
|
- testing
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: critical
|
||||||
|
resourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
validations:
|
||||||
|
- expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume,
|
||||||
|
!has(volume.hostPath))'
|
||||||
|
message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath
|
||||||
|
must be unset.
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t14-binding
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t14
|
||||||
|
spec:
|
||||||
|
policyName: disallow-host-path-t14
|
||||||
|
validationActions:
|
||||||
|
- Audit
|
||||||
|
- Warn
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-any-exclude-resource-match-with-object-selector
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t15
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t15
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: host-path
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: critical
|
||||||
|
exclude:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
names:
|
||||||
|
- "testing"
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||||
|
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."
|
|
@ -0,0 +1,43 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t15
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t15
|
||||||
|
spec:
|
||||||
|
failurePolicy: Fail
|
||||||
|
matchConstraints:
|
||||||
|
excludeResourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resourceNames:
|
||||||
|
- testing
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
objectSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: critical
|
||||||
|
resourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
validations:
|
||||||
|
- expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume,
|
||||||
|
!has(volume.hostPath))'
|
||||||
|
message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath
|
||||||
|
must be unset.
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t15-binding
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t15
|
||||||
|
spec:
|
||||||
|
policyName: disallow-host-path-t15
|
||||||
|
validationActions:
|
||||||
|
- Audit
|
||||||
|
- Warn
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-any-exclude-resource
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t13
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t13
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: host-path
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
- StatefulSet
|
||||||
|
- ReplicaSet
|
||||||
|
- DaemonSet
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
exclude:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
names:
|
||||||
|
- "testing"
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||||
|
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."
|
|
@ -0,0 +1,43 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t13
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t13
|
||||||
|
spec:
|
||||||
|
failurePolicy: Fail
|
||||||
|
matchConstraints:
|
||||||
|
excludeResourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resourceNames:
|
||||||
|
- testing
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
resourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
- statefulsets
|
||||||
|
- replicasets
|
||||||
|
- daemonsets
|
||||||
|
validations:
|
||||||
|
- expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume,
|
||||||
|
!has(volume.hostPath))'
|
||||||
|
message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath
|
||||||
|
must be unset.
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t13-binding
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: disallow-host-path-t13
|
||||||
|
spec:
|
||||||
|
policyName: disallow-host-path-t13
|
||||||
|
validationActions:
|
||||||
|
- Audit
|
||||||
|
- Warn
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-match-kind-with-wildcard
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: check-label-app5
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: check-label-app5
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: check-label-app
|
||||||
|
match:
|
||||||
|
all:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- '*'
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
namespaces:
|
||||||
|
- production
|
||||||
|
- staging
|
||||||
|
exclude:
|
||||||
|
all:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- "Deployment"
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "'app' in object.metadata.labels"
|
|
@ -0,0 +1,41 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: check-label-app5
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: check-label-app5
|
||||||
|
spec:
|
||||||
|
failurePolicy: Fail
|
||||||
|
matchConstraints:
|
||||||
|
excludeResourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
apiVersions:
|
||||||
|
- v1
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
resources:
|
||||||
|
- deployments
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: kubernetes.io/metadata.name
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- production
|
||||||
|
- staging
|
||||||
|
resourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- '*'
|
||||||
|
apiVersions:
|
||||||
|
- '*'
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
resources:
|
||||||
|
- '*'
|
||||||
|
scope: '*'
|
||||||
|
validations:
|
||||||
|
- expression: '''app'' in object.metadata.labels'
|
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: check-label-app5-binding
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: check-label-app5
|
||||||
|
spec:
|
||||||
|
policyName: check-label-app5
|
||||||
|
validationActions:
|
||||||
|
- Audit
|
||||||
|
- Warn
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-exclude-resources-in-specific-namespace
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- error:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- error:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t17
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
validatingadmissionpolicy:
|
||||||
|
generated: false
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t17
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: host-path
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
exclude:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
namespaces:
|
||||||
|
- testing-ns
|
||||||
|
- staging-ns
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||||
|
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."
|
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t17
|
||||||
|
spec: {}
|
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: disallow-host-path-t17-binding
|
||||||
|
spec: {}
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-exclude-resources-with-namespace-selector
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- error:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- error:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,36 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: disallow-host-path-t10
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: host-path
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
exclude:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Deployment
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: type
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- connector
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))"
|
||||||
|
message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset."
|
|
@ -2,7 +2,7 @@ apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
kind: Test
|
kind: Test
|
||||||
metadata:
|
metadata:
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
name: cpol-exclude
|
name: cpol-exclude-resources-with-object-selector
|
||||||
spec:
|
spec:
|
||||||
steps:
|
steps:
|
||||||
- name: step-01
|
- name: step-01
|
|
@ -14,8 +14,11 @@ spec:
|
||||||
exclude:
|
exclude:
|
||||||
any:
|
any:
|
||||||
- resources:
|
- resources:
|
||||||
namespaces:
|
kinds:
|
||||||
- default
|
- Pod
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: critical
|
||||||
validate:
|
validate:
|
||||||
cel:
|
cel:
|
||||||
expressions:
|
expressions:
|
|
@ -2,7 +2,7 @@ apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
kind: Test
|
kind: Test
|
||||||
metadata:
|
metadata:
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
name: cpol-exclude-namespace
|
name: cpol-exclude-user-and-roles
|
||||||
spec:
|
spec:
|
||||||
steps:
|
steps:
|
||||||
- name: step-01
|
- name: step-01
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: check-label-app1
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
validatingadmissionpolicy:
|
||||||
|
generated: false
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: check-label-app1
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: check-label-app
|
||||||
|
match:
|
||||||
|
any:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- Pod
|
||||||
|
exclude:
|
||||||
|
any:
|
||||||
|
- clusterRoles:
|
||||||
|
- cluster-admin
|
||||||
|
- subjects:
|
||||||
|
- kind: User
|
||||||
|
name: John
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "'app' in object.metadata.labels"
|
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: check-label-app1
|
||||||
|
spec: {}
|
|
@ -0,0 +1,7 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: check-label-app1-binding
|
||||||
|
spec: {}
|
Loading…
Add table
Reference in a new issue