Skip to content

Commit 4db50cb

Browse files
authored
(feat) support remote YAML sources in PolicyRefs (#1721)
Add a url field to PolicyRef so ClusterProfile/Profile can reference YAML content served over HTTP/HTTPS, bypassing the ~1 MB ConfigMap size limit. When url is set, Sveltos fetches the content on every reconciliation and redeploys if the hash has changed. A periodic requeue (default 5 minutes, configurable via interval) drives change detection without requiring a Kubernetes watch event. Optional auth is supported via a secretRef pointing to a Secret with token, username+password or caFile keys. Set template: true to have the fetched content treated as a Go template, equivalent to the projectsveltos.io/template annotation on a ConfigMap. ```yaml policyRefs: - deploymentType: Remote remoteURL: interval: 1h0m0s url: https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml ```
1 parent 967860f commit 4db50cb

14 files changed

Lines changed: 1169 additions & 77 deletions

api/v1beta1/spec.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,25 +611,30 @@ type TemplateResourceRef struct {
611611
IgnoreStatusChanges bool `json:"ignoreStatusChanges,omitempty"`
612612
}
613613

614+
// +kubebuilder:validation:XValidation:rule="has(self.remoteURL) != has(self.kind)",message="either remoteURL or kind must be set, but not both"
614615
type PolicyRef struct {
615616
// Namespace of the referenced resource.
616617
// For ClusterProfile namespace can be left empty. In such a case, namespace will
617618
// be implicit set to cluster's namespace.
618619
// For Profile namespace must be left empty. Profile namespace will be used.
619620
// Namespace can be expressed as a template and instantiate using any cluster field.
621+
// Not used when RemoteURL is set.
620622
// +optional
621623
Namespace string `json:"namespace,omitempty"`
622624

623625
// Name of the referenced resource.
624626
// Name can be expressed as a template and instantiate using any cluster field.
625-
// +kubebuilder:validation:MinLength=1
626-
Name string `json:"name"`
627+
// Required when RemoteURL is not set.
628+
// +optional
629+
Name string `json:"name,omitempty"`
627630

628631
// Kind of the resource. Supported kinds are:
629632
// - ConfigMap/Secret
630633
// - flux GitRepository;OCIRepository;Bucket
634+
// Required when RemoteURL is not set.
631635
// +kubebuilder:validation:Enum=GitRepository;OCIRepository;Bucket;ConfigMap;Secret
632-
Kind string `json:"kind"`
636+
// +optional
637+
Kind string `json:"kind,omitempty"`
633638

634639
// Path to the directory containing the YAML files.
635640
// Defaults to 'None', which translates to the root path of the SourceRef.
@@ -671,6 +676,40 @@ type PolicyRef struct {
671676
// +kubebuilder:default:=false
672677
// +optional
673678
SkipNamespaceCreation bool `json:"skipNamespaceCreation,omitempty"`
679+
680+
// RemoteURL configures fetching content from an HTTP/HTTPS endpoint.
681+
// When set, Kind/Name/Namespace must be omitted.
682+
// +optional
683+
RemoteURL *RemoteURL `json:"remoteURL,omitempty"`
684+
}
685+
686+
// RemoteURL groups all fields related to fetching policy content from an HTTP/HTTPS endpoint.
687+
type RemoteURL struct {
688+
// URL is an HTTP/HTTPS endpoint serving raw YAML/JSON/KYAML content.
689+
// Sveltos fetches the content on every reconciliation and redeploys if the
690+
// content hash has changed.
691+
// +kubebuilder:validation:Pattern=`^https?://`
692+
URL string `json:"url"`
693+
694+
// Interval defines how often Sveltos re-fetches the URL to detect changes.
695+
// Defaults to 5 minutes.
696+
// +optional
697+
Interval *metav1.Duration `json:"interval,omitempty"`
698+
699+
// SecretRef references a Secret in the management cluster containing optional
700+
// credentials for fetching the URL. Supported Secret keys:
701+
// "token" — Bearer token (Authorization: Bearer <token>)
702+
// "username"+"password" — HTTP Basic Auth
703+
// "caFile" — PEM-encoded CA certificate for TLS verification
704+
// +optional
705+
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
706+
707+
// Template indicates that the content served at URL is a Go template that
708+
// must be instantiated using cluster fields and templateResourceRefs values
709+
// before deployment. Equivalent to the projectsveltos.io/template annotation
710+
// on a ConfigMap or Secret.
711+
// +optional
712+
Template bool `json:"template,omitempty"`
674713
}
675714

676715
type Clusters struct {

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 42 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,7 @@ spec:
977977
Kind of the resource. Supported kinds are:
978978
- ConfigMap/Secret
979979
- flux GitRepository;OCIRepository;Bucket
980+
Required when RemoteURL is not set.
980981
enum:
981982
- GitRepository
982983
- OCIRepository
@@ -988,7 +989,7 @@ spec:
988989
description: |-
989990
Name of the referenced resource.
990991
Name can be expressed as a template and instantiate using any cluster field.
991-
minLength: 1
992+
Required when RemoteURL is not set.
992993
type: string
993994
namespace:
994995
description: |-
@@ -997,6 +998,7 @@ spec:
997998
be implicit set to cluster's namespace.
998999
For Profile namespace must be left empty. Profile namespace will be used.
9991000
Namespace can be expressed as a template and instantiate using any cluster field.
1001+
Not used when RemoteURL is set.
10001002
type: string
10011003
optional:
10021004
default: false
@@ -1011,6 +1013,52 @@ spec:
10111013
Defaults to 'None', which translates to the root path of the SourceRef.
10121014
Used only for GitRepository;OCIRepository;Bucket
10131015
type: string
1016+
remoteURL:
1017+
description: |-
1018+
RemoteURL configures fetching content from an HTTP/HTTPS endpoint.
1019+
When set, Kind/Name/Namespace must be omitted.
1020+
properties:
1021+
interval:
1022+
description: |-
1023+
Interval defines how often Sveltos re-fetches the URL to detect changes.
1024+
Defaults to 5 minutes.
1025+
type: string
1026+
secretRef:
1027+
description: |-
1028+
SecretRef references a Secret in the management cluster containing optional
1029+
credentials for fetching the URL. Supported Secret keys:
1030+
"token" — Bearer token (Authorization: Bearer <token>)
1031+
"username"+"password" — HTTP Basic Auth
1032+
"caFile" — PEM-encoded CA certificate for TLS verification
1033+
properties:
1034+
name:
1035+
default: ""
1036+
description: |-
1037+
Name of the referent.
1038+
This field is effectively required, but due to backwards compatibility is
1039+
allowed to be empty. Instances of this type with an empty value here are
1040+
almost certainly wrong.
1041+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
1042+
type: string
1043+
type: object
1044+
x-kubernetes-map-type: atomic
1045+
template:
1046+
description: |-
1047+
Template indicates that the content served at URL is a Go template that
1048+
must be instantiated using cluster fields and templateResourceRefs values
1049+
before deployment. Equivalent to the projectsveltos.io/template annotation
1050+
on a ConfigMap or Secret.
1051+
type: boolean
1052+
url:
1053+
description: |-
1054+
URL is an HTTP/HTTPS endpoint serving raw YAML/JSON/KYAML content.
1055+
Sveltos fetches the content on every reconciliation and redeploys if the
1056+
content hash has changed.
1057+
pattern: ^https?://
1058+
type: string
1059+
required:
1060+
- url
1061+
type: object
10141062
skipNamespaceCreation:
10151063
default: false
10161064
description: |-
@@ -1034,10 +1082,10 @@ spec:
10341082
format: int32
10351083
minimum: 1
10361084
type: integer
1037-
required:
1038-
- kind
1039-
- name
10401085
type: object
1086+
x-kubernetes-validations:
1087+
- message: either remoteURL or kind must be set, but not both
1088+
rule: has(self.remoteURL) != has(self.kind)
10411089
type: array
10421090
x-kubernetes-list-type: atomic
10431091
postDeleteChecks:

0 commit comments

Comments
 (0)