Skip to content

Commit

Permalink
Feature: add yurtappset v1beta1
Browse files Browse the repository at this point in the history
  • Loading branch information
luc99hen committed Feb 5, 2024
1 parent da03883 commit c3bfe1a
Show file tree
Hide file tree
Showing 52 changed files with 4,337 additions and 3,140 deletions.
3 changes: 3 additions & 0 deletions charts/yurt-manager/crds/apps.openyurt.io_yurtappdaemons.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ spec:
jsonPath: .status.overriderRef
name: OverriderRef
type: string
deprecated: true
deprecationWarning: apps.openyurt.io/v1alpha1 YurtAppDaemon is deprecated; use
apps.openyurt.io/v1beta1 YurtAppSet;
name: v1alpha1
schema:
openAPIV3Schema:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ spec:
jsonPath: .metadata.creationTimestamp
name: AGE
type: date
deprecated: true
deprecationWarning: apps.openyurt.io/v1alpha1 YurtAppOverrider is deprecated;
use apps.openyurt.io/v1beta1 YurtAppSet WorkloadTweaks;
name: v1alpha1
schema:
openAPIV3Schema:
Expand Down
875 changes: 525 additions & 350 deletions charts/yurt-manager/crds/apps.openyurt.io_yurtappsets.yaml

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions charts/yurt-manager/templates/yurt-manager-auto-generated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -675,18 +675,19 @@ webhooks:
sideEffects: None
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: yurt-manager-webhook-service
namespace: {{ .Release.Namespace }}
path: /mutate-apps-openyurt-io-v1alpha1-yurtappset
path: /mutate-apps-openyurt-io-v1beta1-yurtappset
failurePolicy: Fail
name: myurtappset.kb.io
rules:
- apiGroups:
- apps.openyurt.io
apiVersions:
- v1alpha1
- v1beta1
operations:
- CREATE
- UPDATE
Expand Down Expand Up @@ -848,18 +849,19 @@ webhooks:
sideEffects: None
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: yurt-manager-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-apps-openyurt-io-v1alpha1-yurtappset
path: /validate-apps-openyurt-io-v1beta1-yurtappset
failurePolicy: Fail
name: vyurtappset.kb.io
rules:
- apiGroups:
- apps.openyurt.io
apiVersions:
- v1alpha1
- v1beta1
operations:
- CREATE
- UPDATE
Expand Down
2 changes: 1 addition & 1 deletion hack/make-rules/kustomize_to_chart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ YURT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)"

SUFFIX="auto_generated"

Conversion_Files=("apps.openyurt.io_nodepools.yaml" "raven.openyurt.io_gateways.yaml")
Conversion_Files=("apps.openyurt.io_nodepools.yaml" "raven.openyurt.io_gateways.yaml" "apps.openyurt.io_yurtappsets.yaml")

while [ $# -gt 0 ];do
case $1 in
Expand Down
1 change: 0 additions & 1 deletion pkg/apis/apps/v1alpha1/nodepool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ type NodePoolStatus struct {
}

// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster,path=nodepools,shortName=np,categories=all
// +kubebuilder:subresource:status
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/apps/v1alpha1/yurtappdaemon_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ type YurtAppDaemonCondition struct {
// +kubebuilder:printcolumn:name="WorkloadTemplate",type="string",JSONPath=".status.templateType",description="The WorkloadTemplate Type."
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp",description="CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC."
// +kubebuilder:printcolumn:name="OverriderRef",type="string",JSONPath=".status.overriderRef",description="The name of overrider bound to this yurtappdaemon"
// +kubebuilder:deprecatedversion:warning="apps.openyurt.io/v1alpha1 YurtAppDaemon is deprecated; use apps.openyurt.io/v1beta1 YurtAppSet;"

// YurtAppDaemon is the Schema for the samples API
type YurtAppDaemon struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/apps/v1alpha1/yurtappoverrider_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type Subject struct {
// +kubebuilder:printcolumn:name="Subject",type="string",JSONPath=".subject.kind",description="The subject kind of this overrider."
// +kubebuilder:printcolumn:name="Name",type="string",JSONPath=".subject.name",description="The subject name of this overrider."
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp",description="CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC."
// +kubebuilder:deprecatedversion:warning="apps.openyurt.io/v1alpha1 YurtAppOverrider is deprecated; use apps.openyurt.io/v1beta1 YurtAppSet WorkloadTweaks;"

type YurtAppOverrider struct {
metav1.TypeMeta `json:",inline"`
Expand Down
195 changes: 174 additions & 21 deletions pkg/apis/apps/v1alpha1/yurtappset_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,183 @@ limitations under the License.

package v1alpha1

/*
Implementing the hub method is pretty easy -- we just have to add an empty
method called Hub() to serve as a
[marker](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub).
*/
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/conversion"

"github.com/openyurtio/openyurt/pkg/apis/apps/v1beta1"
"github.com/openyurtio/openyurt/pkg/projectinfo"
)

func (src *YurtAppSet) ConvertTo(dstRaw conversion.Hub) error {
dst := dstRaw.(*v1beta1.YurtAppSet)

dst.ObjectMeta = src.ObjectMeta

// convert spec
if src.Spec.WorkloadTemplate.DeploymentTemplate != nil {
if dst.Spec.Workload.WorkloadTemplate.DeploymentTemplate == nil {
dst.Spec.Workload.WorkloadTemplate.DeploymentTemplate = &v1beta1.DeploymentTemplateSpec{}
}
src.Spec.WorkloadTemplate.DeploymentTemplate.ObjectMeta.DeepCopyInto(&dst.Spec.Workload.WorkloadTemplate.DeploymentTemplate.ObjectMeta)
src.Spec.WorkloadTemplate.DeploymentTemplate.Spec.DeepCopyInto(&dst.Spec.Workload.WorkloadTemplate.DeploymentTemplate.Spec)
}

if src.Spec.WorkloadTemplate.StatefulSetTemplate != nil {
if dst.Spec.Workload.WorkloadTemplate.StatefulSetTemplate == nil {
dst.Spec.Workload.WorkloadTemplate.StatefulSetTemplate = &v1beta1.StatefulSetTemplateSpec{}
}
src.Spec.WorkloadTemplate.StatefulSetTemplate.ObjectMeta.DeepCopyInto(&dst.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.ObjectMeta)
src.Spec.WorkloadTemplate.StatefulSetTemplate.Spec.DeepCopyInto(&dst.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.Spec)
}

pools := make([]string, 0)
tweaks := make([]v1beta1.WorkloadTweak, 0)
for _, pool := range src.Spec.Topology.Pools {
if len(pool.NodeSelectorTerm.MatchExpressions) == 1 && pool.NodeSelectorTerm.MatchExpressions[0].Key == projectinfo.GetNodePoolLabel() ||
pool.NodeSelectorTerm.MatchExpressions[0].Operator == corev1.NodeSelectorOpIn {
pools = append(pools, pool.NodeSelectorTerm.MatchExpressions[0].Values...)
if pool.Replicas != nil {
tweaks = append(tweaks, v1beta1.WorkloadTweak{
Pools: pool.NodeSelectorTerm.MatchExpressions[0].Values,
Tweaks: v1beta1.Tweaks{
Replicas: pool.Replicas,
},
})
}
}
}
dst.Spec.Pools = pools
dst.Spec.Workload.WorkloadTweaks = tweaks
dst.Spec.RevisionHistoryLimit = src.Spec.RevisionHistoryLimit

// convert status
dst.Status.ObservedGeneration = src.Status.ObservedGeneration
dst.Status.CollisionCount = src.Status.CollisionCount
dst.Status.TotalWorkloads = int32(len(src.Status.PoolReplicas))
dst.Status.CurrentRevision = src.Status.CurrentRevision
dst.Status.Conditions = make([]v1beta1.YurtAppSetCondition, 0)
for _, condition := range src.Status.Conditions {
dst.Status.Conditions = append(dst.Status.Conditions,
v1beta1.YurtAppSetCondition{
Type: v1beta1.YurtAppSetConditionType(condition.Type),
Status: condition.Status,
LastTransitionTime: condition.LastTransitionTime,
Reason: condition.Reason,
Message: condition.Message,
})
}
readyWorkloads := 0
for _, workload := range src.Status.WorkloadSummaries {
if workload.Replicas != workload.ReadyReplicas {
readyWorkloads++
}
}
dst.Status.ReadyWorkloads = int32(readyWorkloads)

klog.V(4).Infof("convert from v1alpha1 to v1beta1 for yurtappset %s", src.Name)
return nil
}

func (dst *YurtAppSet) ConvertFrom(srcRaw conversion.Hub) error {
src := srcRaw.(*v1beta1.YurtAppSet)
var defaultReplicas int32

dst.ObjectMeta = src.ObjectMeta

// convert spec
dst.Spec.Selector = &metav1.LabelSelector{}
if src.Spec.Workload.WorkloadTemplate.DeploymentTemplate != nil {
if dst.Spec.WorkloadTemplate.DeploymentTemplate == nil {
dst.Spec.WorkloadTemplate.DeploymentTemplate = &DeploymentTemplateSpec{}
}
src.Spec.Workload.WorkloadTemplate.DeploymentTemplate.ObjectMeta.DeepCopyInto(&dst.Spec.WorkloadTemplate.DeploymentTemplate.ObjectMeta)
src.Spec.Workload.WorkloadTemplate.DeploymentTemplate.Spec.DeepCopyInto(&dst.Spec.WorkloadTemplate.DeploymentTemplate.Spec)
if src.Spec.Workload.WorkloadTemplate.DeploymentTemplate.Spec.Replicas != nil {
defaultReplicas = *src.Spec.Workload.WorkloadTemplate.DeploymentTemplate.Spec.Replicas
} else {
defaultReplicas = 0
}

if src.Spec.Workload.WorkloadTemplate.DeploymentTemplate.Spec.Selector != nil {
dst.Spec.WorkloadTemplate.DeploymentTemplate.Spec.Selector.DeepCopyInto(dst.Spec.Selector)
}
dst.Status.TemplateType = DeploymentTemplateType
}

if src.Spec.Workload.WorkloadTemplate.StatefulSetTemplate != nil {
if dst.Spec.WorkloadTemplate.StatefulSetTemplate == nil {
dst.Spec.WorkloadTemplate.StatefulSetTemplate = &StatefulSetTemplateSpec{}
}
src.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.ObjectMeta.DeepCopyInto(&dst.Spec.WorkloadTemplate.StatefulSetTemplate.ObjectMeta)
src.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.Spec.DeepCopyInto(&dst.Spec.WorkloadTemplate.StatefulSetTemplate.Spec)
if src.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.Spec.Replicas != nil {
defaultReplicas = *src.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.Spec.Replicas
} else {
defaultReplicas = 0
}

if src.Spec.Workload.WorkloadTemplate.StatefulSetTemplate.Spec.Selector != nil {
dst.Spec.WorkloadTemplate.StatefulSetTemplate.Spec.Selector.DeepCopyInto(dst.Spec.Selector)
}
dst.Status.TemplateType = StatefulSetTemplateType
}

poolTweaks := make(map[string]*Pool, 0)
for _, poolName := range src.Spec.Pools {
poolTweaks[poolName] = &Pool{
Name: poolName,
NodeSelectorTerm: corev1.NodeSelectorTerm{
MatchExpressions: []corev1.NodeSelectorRequirement{
{
Key: projectinfo.GetNodePoolLabel(),
Operator: corev1.NodeSelectorOpIn,
Values: []string{poolName},
},
},
},
Replicas: &defaultReplicas,
}
}

// NOTE !!!!!! @kadisi
// If this version is storageversion, you only need to uncommand this method
for _, tweak := range src.Spec.Workload.WorkloadTweaks {
for _, poolName := range tweak.Pools {
if _, ok := poolTweaks[poolName]; ok && tweak.Tweaks.Replicas != nil {
poolTweaks[poolName].Replicas = tweak.Tweaks.Replicas
}
}
}

// Hub marks this type as a conversion hub.
//func (*YurtAppSet) Hub() {}
for _, tweak := range poolTweaks {
dst.Spec.Topology.Pools = append(dst.Spec.Topology.Pools, *tweak)
}

// NOTE !!!!!!! @kadisi
// If this version is not storageversion, you need to implement the ConvertTo and ConvertFrom methods
// convert status
dst.Status.ObservedGeneration = src.Status.ObservedGeneration
dst.Status.CollisionCount = src.Status.CollisionCount
dst.Status.CurrentRevision = src.Status.CurrentRevision
dst.Status.Conditions = make([]YurtAppSetCondition, 0)
// this is just an estimate, because the real value can not be obtained from v1beta1 status
dst.Status.ReadyReplicas = src.Status.ReadyWorkloads * defaultReplicas
dst.Status.Replicas = src.Status.TotalWorkloads * defaultReplicas

// need import "sigs.k8s.io/controller-runtime/pkg/conversion"
//func (src *YurtAppSet) ConvertTo(dstRaw conversion.Hub) error {
// return nil
//}
dst.Status.PoolReplicas = make(map[string]int32)
for _, pool := range src.Spec.Pools {
dst.Status.PoolReplicas[pool] = defaultReplicas
}

// NOTE !!!!!!! @kadisi
// If this version is not storageversion, you need to implement the ConvertTo and ConvertFrom methods
for _, condition := range src.Status.Conditions {
dst.Status.Conditions = append(dst.Status.Conditions, YurtAppSetCondition{
Type: YurtAppSetConditionType(condition.Type),
Status: condition.Status,
LastTransitionTime: condition.LastTransitionTime,
Reason: condition.Reason,
Message: condition.Message,
})
}

// need import "sigs.k8s.io/controller-runtime/pkg/conversion"
//func (dst *YurtAppSet) ConvertFrom(srcRaw conversion.Hub) error {
// return nil
//}
klog.V(4).Infof("convert from v1beta1 to v1alpha1 for yurtappset %s", src.Name)
return nil
}
3 changes: 2 additions & 1 deletion pkg/apis/apps/v1alpha1/yurtappset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,13 @@ type YurtAppSetCondition struct {

// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=yas,categories=all
// +kubebuilder:subresource:status
// +kubebuilder:resource:shortName=yas
// +kubebuilder:printcolumn:name="READY",type="integer",JSONPath=".status.readyReplicas",description="The number of pods ready."
// +kubebuilder:printcolumn:name="WorkloadTemplate",type="string",JSONPath=".status.templateType",description="The WorkloadTemplate Type."
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp",description="CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC."
// +kubebuilder:printcolumn:name="OverriderRef",type="string",JSONPath=".status.overriderRef",description="The name of overrider bound to this yurtappset"
// +kubebuilder:deprecatedversion:warning="apps.openyurt.io/v1alpha1 YurtAppSet is deprecated; use apps.openyurt.io/v1beta1 YurtAppSet; v1alpha1 YurtAppSet.Status.WorkloadSummary should not be used"

// YurtAppSet is the Schema for the yurtAppSets API
type YurtAppSet struct {
Expand Down
1 change: 0 additions & 1 deletion pkg/apis/apps/v1beta1/nodepool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ type NodePoolStatus struct {
Nodes []string `json:"nodes,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster,path=nodepools,shortName=np,categories=all
Expand Down
26 changes: 26 additions & 0 deletions pkg/apis/apps/v1beta1/yurtappset_conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright 2023 The OpenYurt 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 v1beta1

/*
Implementing the hub method is pretty easy -- we just have to add an empty
method called `Hub()` to serve as a
[marker](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/conversion?tab=doc#Hub).
*/

// Hub marks this type as a conversion hub.
func (*YurtAppSet) Hub() {}
Loading

0 comments on commit c3bfe1a

Please sign in to comment.