Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions apis/placement/v1alpha1/envelope_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
Copyright 2025 The KubeFleet Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// +genclient
// +genclient:nonNamespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope="Cluster",categories={fleet,fleet-placement}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterResourceEnvelope wraps cluster-scoped resources for placement.
type ClusterResourceEnvelope struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// The desired state of ClusterResourceEnvelope.
// +kubebuilder:validation:Required
Spec EnvelopeSpec `json:"spec"`
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: we keep the spec field here just as a common practice; if necessary we could expose the inner object directly to reduce nesting.


// The observed status of ClusterResourceEnvelope.
// +kubebuilder:validation:Optional
Status ClusterResourceEnvelopeStatus `json:"status,omitempty"`
}

// EnvelopeSpec helps wrap resources for placement.
type EnvelopeSpec struct {
// A map of wrapped manifests.
//
// Each manifest is uniquely identified by a string key, typically a filename that represents
// the manifest.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=50
Manifests map[string]Manifest `json:"manifests"`
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: a map is used here to make sure that each manifest is uniquely identified with a key, which can later be used in status reporting.

}

// Manifest is a wrapped resource.
type Manifest struct {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could put the YAML content directly as the map value; it is now wrapped in a struct just in case we might need to add some resource-specific options in the future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, in earlier discussions we have received requests regarding the possibility of doing API server validation on wrapped resources as an extra layer of defense -> if implemented, we might need to have a bypassValidation option here to allow wrapping of resources that are expected to fail API server validation (e.g., the corresponding API is only available on the member cluster side, or a mutating webhook is expected to modify the object on the member cluster side).

// The resource data.
// +kubebuilder:validation:Required
// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:pruning:PreserveUnknownFields
Data runtime.RawExtension `json:"data"`
}

// ClusterResourceEnvelopeStatus is the observed status of a ClusterResourceEnvelope.
type ClusterResourceEnvelopeStatus struct {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The status fields are added just in case in the future we might want to implement additional checks for wrapped resources. In the initial stage this might not be necessary, and it should be safe for us to drop these fields at first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not add status now as we can always add them later

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will drop the status field 👌

// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
//
// Conditions is an array of current observed conditions for ClusterResourceEnvelope.
// +kubebuilder:validation:Optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ManifestConditions is an array of current observed conditions for each manifest in the envelope.
// +kubebuilder:validation:Optional
ManifestConditions []ManifestCondition `json:"manifestConditions,omitempty"`
}

// ManifestCondition is the observed conditions of a wrapped manifest.
type ManifestCondition struct {
// The name of the manifest.
// +kubebuilder:validation:Required
Name string `json:"name"`

// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
//
// Conditions is an array of current observed conditions for a wrapped manifest.
// +kubebuilder:validation:Optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope="Namespaced",categories={fleet,fleet-placement}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ResourceEnvelope struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// The desired state of ResourceEnvelope.
// +kubebuilder:validation:Required
Spec EnvelopeSpec `json:"spec"`

// The observed status of ResourceEnvelope.
// +kubebuilder:validation:Optional
Status ResourceEnvelopeStatus `json:"status,omitempty"`
}

// ResourceEnvelopeStatus is the observed status of a ResourceEnvelope.
type ResourceEnvelopeStatus struct {
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
//
// Conditions is an array of current observed conditions for ResourceEnvelope.
// +kubebuilder:validation:Optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ManifestConditions is an array of current observed conditions for each manifest in the envelope.
// +kubebuilder:validation:Optional
ManifestConditions []ManifestCondition `json:"manifestConditions,omitempty"`
}
174 changes: 173 additions & 1 deletion apis/placement/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading