Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion apis/cluster/v1beta1/zz_generated.deepcopy.go

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

73 changes: 73 additions & 0 deletions apis/placement/v1alpha1/envelope_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
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.

}

// 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"`
}

// +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"`
}
94 changes: 92 additions & 2 deletions apis/placement/v1alpha1/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion apis/placement/v1beta1/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion apis/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.0
name: clusterresourceenvelopes.placement.kubernetes-fleet.io
spec:
group: placement.kubernetes-fleet.io
names:
categories:
- fleet
- fleet-placement
kind: ClusterResourceEnvelope
listKind: ClusterResourceEnvelopeList
plural: clusterresourceenvelopes
singular: clusterresourceenvelope
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: ClusterResourceEnvelope wraps cluster-scoped resources for placement.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: The desired state of ClusterResourceEnvelope.
properties:
manifests:
additionalProperties:
description: Manifest is a wrapped resource.
properties:
data:
description: The resource data.
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
required:
- data
type: object
description: |-
A map of wrapped manifests.

Each manifest is uniquely identified by a string key, typically a filename that represents
the manifest.
maxProperties: 50
minProperties: 1
type: object
required:
- manifests
type: object
required:
- spec
type: object
served: true
storage: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.0
name: resourceenvelopes.placement.kubernetes-fleet.io
spec:
group: placement.kubernetes-fleet.io
names:
categories:
- fleet
- fleet-placement
kind: ResourceEnvelope
listKind: ResourceEnvelopeList
plural: resourceenvelopes
singular: resourceenvelope
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: The desired state of ResourceEnvelope.
properties:
manifests:
additionalProperties:
description: Manifest is a wrapped resource.
properties:
data:
description: The resource data.
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
required:
- data
type: object
description: |-
A map of wrapped manifests.

Each manifest is uniquely identified by a string key, typically a filename that represents
the manifest.
maxProperties: 50
minProperties: 1
type: object
required:
- manifests
type: object
required:
- spec
type: object
served: true
storage: true
Loading
Loading