1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

feat: make any struct common to all api versions (#10553)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2024-06-27 12:09:57 +02:00 committed by GitHub
parent 6f4818d724
commit 1a02b70a1c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 83 additions and 119 deletions

61
api/kyverno/any.go Normal file
View file

@ -0,0 +1,61 @@
package kyverno
import (
"encoding/json"
"github.com/jinzhu/copier"
)
type Value any
// Any can be any type.
// +k8s:deepcopy-gen=false
type Any struct {
// Value contains the value of the Any object.
// +optional
Value `json:"-"`
}
func ToAny(in any) *Any {
var new *Any
if in != nil {
new = &Any{in}
}
return new
}
func FromAny(in *Any) any {
if in == nil {
return nil
}
return in.Value
}
func (in *Any) DeepCopyInto(out *Any) {
if err := copier.Copy(out, in); err != nil {
panic("deep copy failed")
}
}
func (in *Any) DeepCopy() *Any {
if in == nil {
return nil
}
out := new(Any)
in.DeepCopyInto(out)
return out
}
func (a *Any) MarshalJSON() ([]byte, error) {
return json.Marshal(a.Value)
}
func (a *Any) UnmarshalJSON(data []byte) error {
var v any
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
a.Value = v
return nil
}

View file

@ -1,49 +1,9 @@
package v2 package v2
import ( import (
"github.com/jinzhu/copier" "github.com/kyverno/kyverno/api/kyverno"
"k8s.io/apimachinery/pkg/util/json"
) )
type Value any
// Any can be any type.
// +k8s:deepcopy-gen=false
type Any struct {
// Value contains the value of the Any object.
// +optional
Value `json:"-"`
}
func (in *Any) DeepCopyInto(out *Any) {
if err := copier.Copy(out, in); err != nil {
panic("deep copy failed")
}
}
func (in *Any) DeepCopy() *Any {
if in == nil {
return nil
}
out := new(Any)
in.DeepCopyInto(out)
return out
}
func (a *Any) MarshalJSON() ([]byte, error) {
return json.Marshal(a.Value)
}
func (a *Any) UnmarshalJSON(data []byte) error {
var v any
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
a.Value = v
return nil
}
// ConditionOperator is the operation performed on condition key and value. // ConditionOperator is the operation performed on condition key and value.
// +kubebuilder:validation:Enum=Equals;NotEquals;AnyIn;AllIn;AnyNotIn;AllNotIn;GreaterThanOrEquals;GreaterThan;LessThanOrEquals;LessThan;DurationGreaterThanOrEquals;DurationGreaterThan;DurationLessThanOrEquals;DurationLessThan // +kubebuilder:validation:Enum=Equals;NotEquals;AnyIn;AllIn;AnyNotIn;AllNotIn;GreaterThanOrEquals;GreaterThan;LessThanOrEquals;LessThan;DurationGreaterThanOrEquals;DurationGreaterThan;DurationLessThanOrEquals;DurationLessThan
type ConditionOperator string type ConditionOperator string
@ -84,7 +44,7 @@ type Condition struct {
// Key is the context entry (using JMESPath) for conditional rule evaluation. // Key is the context entry (using JMESPath) for conditional rule evaluation.
// +kubebuilder:validation:Schemaless // +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields // +kubebuilder:pruning:PreserveUnknownFields
RawKey *Any `json:"key,omitempty" yaml:"key,omitempty"` RawKey *kyverno.Any `json:"key,omitempty" yaml:"key,omitempty"`
// Operator is the conditional operation to perform. Valid operators are: // Operator is the conditional operation to perform. Valid operators are:
// Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, // Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals,
@ -96,40 +56,26 @@ type Condition struct {
// or can be variables declared using JMESPath. // or can be variables declared using JMESPath.
// +kubebuilder:validation:Schemaless // +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields // +kubebuilder:pruning:PreserveUnknownFields
RawValue *Any `json:"value,omitempty" yaml:"value,omitempty"` RawValue *kyverno.Any `json:"value,omitempty" yaml:"value,omitempty"`
// Message is an optional display message // Message is an optional display message
Message string `json:"message,omitempty" yaml:"message,omitempty"` Message string `json:"message,omitempty" yaml:"message,omitempty"`
} }
func (c *Condition) GetKey() any { func (c *Condition) GetKey() any {
if c.RawKey == nil { return kyverno.FromAny(c.RawKey)
return nil
}
return c.RawKey.Value
} }
func (c *Condition) SetKey(in any) { func (c *Condition) SetKey(in any) {
var new *Any c.RawKey = kyverno.ToAny(in)
if in != nil {
new = &Any{in}
}
c.RawKey = new
} }
func (c *Condition) GetValue() any { func (c *Condition) GetValue() any {
if c.RawValue == nil { return kyverno.FromAny(c.RawValue)
return nil
}
return c.RawValue.Value
} }
func (c *Condition) SetValue(in any) { func (c *Condition) SetValue(in any) {
var new *Any c.RawValue = kyverno.ToAny(in)
if in != nil {
new = &Any{in}
}
c.RawValue = new
} }
type AnyAllConditions struct { type AnyAllConditions struct {

View file

@ -3,15 +3,16 @@ package v2
import ( import (
"testing" "testing"
"github.com/kyverno/kyverno/api/kyverno"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/json"
) )
func TestCondition_Marshal(t *testing.T) { func TestCondition_Marshal(t *testing.T) {
type fields struct { type fields struct {
RawKey *Any RawKey *kyverno.Any
Operator ConditionOperator Operator ConditionOperator
RawValue *Any RawValue *kyverno.Any
Message string Message string
} }
tests := []struct { tests := []struct {
@ -25,11 +26,11 @@ func TestCondition_Marshal(t *testing.T) {
}, { }, {
name: "with key", name: "with key",
fields: fields{ fields: fields{
RawKey: &Any{ RawKey: &kyverno.Any{
Value: "{{ request.object.name }}", Value: "{{ request.object.name }}",
}, },
Operator: ConditionOperators["Equals"], Operator: ConditionOperators["Equals"],
RawValue: &Any{ RawValue: &kyverno.Any{
Value: "dummy", Value: "dummy",
}, },
}, },

View file

@ -5875,40 +5875,6 @@ Kubernetes admission/v1.Operation
</tbody> </tbody>
</table> </table>
<hr /> <hr />
<h3 id="kyverno.io/v2.Any">Any
</h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v2.Condition">Condition</a>)
</p>
<p>
<p>Any can be any type.</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>-</code><br/>
<em>
<a href="#kyverno.io/v2.Value">
Value
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Value contains the value of the Any object.</p>
</td>
</tr>
</tbody>
</table>
<hr />
<h3 id="kyverno.io/v2.AnyAllConditions">AnyAllConditions <h3 id="kyverno.io/v2.AnyAllConditions">AnyAllConditions
</h3> </h3>
<p> <p>
@ -6126,9 +6092,7 @@ Kubernetes meta/v1.Time
<td> <td>
<code>key</code><br/> <code>key</code><br/>
<em> <em>
<a href="#kyverno.io/v2.Any"> github.com/kyverno/kyverno/api/kyverno.Any
Any
</a>
</em> </em>
</td> </td>
<td> <td>
@ -6155,9 +6119,7 @@ DurationLessThanOrEquals, DurationLessThan</p>
<td> <td>
<code>value</code><br/> <code>value</code><br/>
<em> <em>
<a href="#kyverno.io/v2.Any"> github.com/kyverno/kyverno/api/kyverno.Any
Any
</a>
</em> </em>
</td> </td>
<td> <td>
@ -6615,14 +6577,6 @@ int
</tbody> </tbody>
</table> </table>
<hr /> <hr />
<h3 id="kyverno.io/v2.Value">Value
</h3>
<p>
(<em>Appears on:</em>
<a href="#kyverno.io/v2.Any">Any</a>)
</p>
<p>
</p>
<h2 id="kyverno.io/v2alpha1">kyverno.io/v2alpha1</h2> <h2 id="kyverno.io/v2alpha1">kyverno.io/v2alpha1</h2>
<p> <p>
</p> </p>

View file

@ -19,15 +19,16 @@ limitations under the License.
package v2 package v2
import ( import (
kyverno "github.com/kyverno/kyverno/api/kyverno"
v2 "github.com/kyverno/kyverno/api/kyverno/v2" v2 "github.com/kyverno/kyverno/api/kyverno/v2"
) )
// ConditionApplyConfiguration represents an declarative configuration of the Condition type for use // ConditionApplyConfiguration represents an declarative configuration of the Condition type for use
// with apply. // with apply.
type ConditionApplyConfiguration struct { type ConditionApplyConfiguration struct {
RawKey *v2.Any `json:"key,omitempty"` RawKey *kyverno.Any `json:"key,omitempty"`
Operator *v2.ConditionOperator `json:"operator,omitempty"` Operator *v2.ConditionOperator `json:"operator,omitempty"`
RawValue *v2.Any `json:"value,omitempty"` RawValue *kyverno.Any `json:"value,omitempty"`
Message *string `json:"message,omitempty"` Message *string `json:"message,omitempty"`
} }
@ -40,7 +41,7 @@ func Condition() *ConditionApplyConfiguration {
// WithRawKey sets the RawKey field in the declarative configuration to the given value // WithRawKey sets the RawKey field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the RawKey field is set to the value of the last call. // If called multiple times, the RawKey field is set to the value of the last call.
func (b *ConditionApplyConfiguration) WithRawKey(value v2.Any) *ConditionApplyConfiguration { func (b *ConditionApplyConfiguration) WithRawKey(value kyverno.Any) *ConditionApplyConfiguration {
b.RawKey = &value b.RawKey = &value
return b return b
} }
@ -56,7 +57,7 @@ func (b *ConditionApplyConfiguration) WithOperator(value v2.ConditionOperator) *
// WithRawValue sets the RawValue field in the declarative configuration to the given value // WithRawValue sets the RawValue field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the RawValue field is set to the value of the last call. // If called multiple times, the RawValue field is set to the value of the last call.
func (b *ConditionApplyConfiguration) WithRawValue(value v2.Any) *ConditionApplyConfiguration { func (b *ConditionApplyConfiguration) WithRawValue(value kyverno.Any) *ConditionApplyConfiguration {
b.RawValue = &value b.RawValue = &value
return b return b
} }

View file

@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/kyverno/kyverno/api/kyverno"
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2" kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
"github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/config"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
@ -34,11 +35,11 @@ func Test_checkCondition(t *testing.T) {
logger: logging.GlobalLogger(), logger: logging.GlobalLogger(),
ctx: ctx, ctx: ctx,
condition: kyvernov2.Condition{ condition: kyvernov2.Condition{
RawKey: &kyvernov2.Any{ RawKey: &kyverno.Any{
Value: "{{ request.object.name }}", Value: "{{ request.object.name }}",
}, },
Operator: kyvernov2.ConditionOperators["Equals"], Operator: kyvernov2.ConditionOperators["Equals"],
RawValue: &kyvernov2.Any{ RawValue: &kyverno.Any{
Value: "dummy", Value: "dummy",
}, },
}, },