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

feat: update refreshInterval in globalcontext CRD to use a duration (#9615)

This commit is contained in:
Vishal Choudhary 2024-02-02 17:36:51 +05:30 committed by GitHub
parent 03af9831f3
commit 10ae9e306c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 52 additions and 43 deletions

View file

@ -16,6 +16,8 @@ limitations under the License.
package v2alpha1
import (
"time"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
@ -78,7 +80,10 @@ func (c *GlobalContextEntrySpec) IsResource() bool {
// Validate implements programmatic validation
func (c *GlobalContextEntrySpec) Validate(path *field.Path) (errs field.ErrorList) {
if c.IsResource() && c.IsAPICall() {
errs = append(errs, field.Forbidden(path.Child("resource"), "An External API Call entry requires a url"))
errs = append(errs, field.Forbidden(path.Child("kubernetesResource"), "A global context entry should be either have KubernetesResource or APICall"))
}
if !c.IsResource() && !c.IsAPICall() {
errs = append(errs, field.Forbidden(path.Child("kubernetesResource"), "A global context entry should be either have KubernetesResource or APICall"))
}
if c.IsResource() {
errs = append(errs, c.KubernetesResource.Validate(path.Child("resource"))...)
@ -115,13 +120,13 @@ type KubernetesResource struct {
// Validate implements programmatic validation
func (k *KubernetesResource) Validate(path *field.Path) (errs field.ErrorList) {
if k.Group == "" {
errs = append(errs, field.Required(path.Child("group"), "An Resource entry requires a group"))
errs = append(errs, field.Required(path.Child("group"), "A Resource entry requires a group"))
}
if k.Version == "" {
errs = append(errs, field.Required(path.Child("version"), "An Resource entry requires a version"))
errs = append(errs, field.Required(path.Child("version"), "A Resource entry requires a version"))
}
if k.Resource == "" {
errs = append(errs, field.Required(path.Child("resource"), "An Resource entry requires a resource"))
errs = append(errs, field.Required(path.Child("resource"), "A Resource entry requires a resource"))
}
return errs
}
@ -129,9 +134,10 @@ func (k *KubernetesResource) Validate(path *field.Path) (errs field.ErrorList) {
// ExternalAPICall stores infos about API call that should be cached
type ExternalAPICall struct {
kyvernov1.APICall `json:",inline,omitempty"`
// RefreshIntervalSeconds defines the interval at which to poll the APICall
// +kubebuilder:default=0
RefreshIntervalSeconds int64 `json:"refreshIntervalSeconds,omitempty"`
// RefreshInterval defines the interval in duration at which to poll the APICall
// +kubebuilder:validation:Format=duration
// +kubebuilder:default=`10m`
RefreshInterval *metav1.Duration `json:"refreshInterval,omitempty"`
}
// Validate implements programmatic validation
@ -139,8 +145,8 @@ func (e *ExternalAPICall) Validate(path *field.Path) (errs field.ErrorList) {
if e.Service.URL == "" {
errs = append(errs, field.Required(path.Child("url"), "An External API Call entry requires a url"))
}
if e.RefreshIntervalSeconds <= 0 {
errs = append(errs, field.Required(path.Child("refreshIntervalSeconds"), "An Resource entry requires a refresh interval greater than 0 seconds"))
if e.RefreshInterval.Duration == 0*time.Second {
errs = append(errs, field.Required(path.Child("refreshIntervalSeconds"), "A Resource entry requires a refresh interval greater than 0 seconds"))
}
return errs
}

View file

@ -153,6 +153,11 @@ func (in *ClusterCleanupPolicyList) DeepCopyObject() runtime.Object {
func (in *ExternalAPICall) DeepCopyInto(out *ExternalAPICall) {
*out = *in
in.APICall.DeepCopyInto(&out.APICall)
if in.RefreshInterval != nil {
in, out := &in.RefreshInterval, &out.RefreshInterval
*out = new(v1.Duration)
**out = **in
}
return
}

View file

@ -77,12 +77,12 @@ spec:
- GET
- POST
type: string
refreshIntervalSeconds:
default: 0
description: RefreshIntervalSeconds defines the interval at which
to poll the APICall
format: int64
type: integer
refreshInterval:
default: 10m
description: RefreshInterval defines the interval in duration
at which to poll the APICall
format: duration
type: string
service:
description: Service is an API call to a JSON web service
properties:

View file

@ -71,12 +71,12 @@ spec:
- GET
- POST
type: string
refreshIntervalSeconds:
default: 0
description: RefreshIntervalSeconds defines the interval at which
to poll the APICall
format: int64
type: integer
refreshInterval:
default: 10m
description: RefreshInterval defines the interval in duration
at which to poll the APICall
format: duration
type: string
service:
description: Service is an API call to a JSON web service
properties:

View file

@ -28218,12 +28218,12 @@ spec:
- GET
- POST
type: string
refreshIntervalSeconds:
default: 0
description: RefreshIntervalSeconds defines the interval at which
to poll the APICall
format: int64
type: integer
refreshInterval:
default: 10m
description: RefreshInterval defines the interval in duration
at which to poll the APICall
format: duration
type: string
service:
description: Service is an API call to a JSON web service
properties:

View file

@ -8011,13 +8011,15 @@ APICall
</tr>
<tr>
<td>
<code>refreshIntervalSeconds</code><br/>
<code>refreshInterval</code><br/>
<em>
int64
<a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
Kubernetes meta/v1.Duration
</a>
</em>
</td>
<td>
<p>RefreshIntervalSeconds defines the interval at which to poll the APICall</p>
<p>RefreshInterval defines the interval in duration at which to poll the APICall</p>
</td>
</tr>
</tbody>

View file

@ -21,13 +21,14 @@ package v2alpha1
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
v1 "github.com/kyverno/kyverno/pkg/client/applyconfigurations/kyverno/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ExternalAPICallApplyConfiguration represents an declarative configuration of the ExternalAPICall type for use
// with apply.
type ExternalAPICallApplyConfiguration struct {
v1.APICallApplyConfiguration `json:",omitempty,inline"`
RefreshIntervalSeconds *int64 `json:"refreshIntervalSeconds,omitempty"`
RefreshInterval *metav1.Duration `json:"refreshInterval,omitempty"`
}
// ExternalAPICallApplyConfiguration constructs an declarative configuration of the ExternalAPICall type for use with
@ -81,10 +82,10 @@ func (b *ExternalAPICallApplyConfiguration) WithJMESPath(value string) *External
return b
}
// WithRefreshIntervalSeconds sets the RefreshIntervalSeconds field in the declarative configuration to the given value
// WithRefreshInterval sets the RefreshInterval field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the RefreshIntervalSeconds field is set to the value of the last call.
func (b *ExternalAPICallApplyConfiguration) WithRefreshIntervalSeconds(value int64) *ExternalAPICallApplyConfiguration {
b.RefreshIntervalSeconds = &value
// If called multiple times, the RefreshInterval field is set to the value of the last call.
func (b *ExternalAPICallApplyConfiguration) WithRefreshInterval(value metav1.Duration) *ExternalAPICallApplyConfiguration {
b.RefreshInterval = &value
return b
}

View file

@ -2,7 +2,6 @@ package globalcontext
import (
"context"
"errors"
"time"
"github.com/go-logr/logr"
@ -88,12 +87,8 @@ func (c *controller) getEntry(name string) (*kyvernov2alpha1.GlobalContextEntry,
func (c *controller) makeStoreEntry(ctx context.Context, gce *kyvernov2alpha1.GlobalContextEntry) (store.Entry, error) {
// TODO: should be done at validation time
if gce.Spec.KubernetesResource == nil && gce.Spec.APICall == nil {
return nil, errors.New("global context entry neither has K8sResource nor APICall")
}
// TODO: should be done at validation time
if gce.Spec.KubernetesResource != nil && gce.Spec.APICall != nil {
return nil, errors.New("global context entry has both K8sResource and APICall")
if err := gce.Validate(); err != nil {
return nil, err.ToAggregate()
}
if gce.Spec.KubernetesResource != nil {
gvr := schema.GroupVersionResource{
@ -103,5 +98,5 @@ func (c *controller) makeStoreEntry(ctx context.Context, gce *kyvernov2alpha1.Gl
}
return k8sresource.New(ctx, c.dclient.GetDynamicInterface(), gvr, gce.Spec.KubernetesResource.Namespace)
}
return externalapi.New(ctx, logger, adapters.Client(c.dclient), gce.Spec.APICall.APICall, time.Duration(gce.Spec.APICall.RefreshIntervalSeconds))
return externalapi.New(ctx, logger, adapters.Client(c.dclient), gce.Spec.APICall.APICall, gce.Spec.APICall.RefreshInterval.Duration)
}