-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add api for clusterpropagationpolicy resource (#138)
* feat: add api for clusterpropagationpolicy resource Signed-off-by: warjiang <1096409085@qq.com> * fix: add resource kind for clusterpp Signed-off-by: warjiang <1096409085@qq.com> --------- Signed-off-by: warjiang <1096409085@qq.com>
- Loading branch information
Showing
6 changed files
with
306 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package propagationpolicy | ||
|
||
import ( | ||
"context" | ||
"github.com/gin-gonic/gin" | ||
"github.com/karmada-io/dashboard/cmd/api/app/router" | ||
v1 "github.com/karmada-io/dashboard/cmd/api/app/types/api/v1" | ||
"github.com/karmada-io/dashboard/cmd/api/app/types/common" | ||
"github.com/karmada-io/dashboard/pkg/client" | ||
"github.com/karmada-io/dashboard/pkg/common/errors" | ||
"github.com/karmada-io/dashboard/pkg/resource/clusterpropagationpolicy" | ||
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/util/retry" | ||
"k8s.io/klog/v2" | ||
"sigs.k8s.io/yaml" | ||
) | ||
|
||
func handleGetClusterPropagationPolicyList(c *gin.Context) { | ||
karmadaClient := client.InClusterKarmadaClient() | ||
dataSelect := common.ParseDataSelectPathParameter(c) | ||
clusterPropagationList, err := clusterpropagationpolicy.GetClusterPropagationPolicyList(karmadaClient, dataSelect) | ||
if err != nil { | ||
klog.ErrorS(err, "Failed to GetClusterPropagationPolicyList") | ||
common.Fail(c, err) | ||
return | ||
} | ||
common.Success(c, clusterPropagationList) | ||
} | ||
|
||
func handleGetClusterPropagationPolicyDetail(c *gin.Context) { | ||
karmadaClient := client.InClusterKarmadaClient() | ||
name := c.Param("clusterPropagationPolicyName") | ||
result, err := clusterpropagationpolicy.GetClusterPropagationPolicyDetail(karmadaClient, name) | ||
if err != nil { | ||
klog.ErrorS(err, "GetClusterPropagationPolicyDetail failed") | ||
common.Fail(c, err) | ||
return | ||
} | ||
common.Success(c, result) | ||
} | ||
|
||
func handlePostClusterPropagationPolicy(c *gin.Context) { | ||
ctx := context.Context(c) | ||
propagationpolicyRequest := new(v1.PostPropagationPolicyRequest) | ||
if err := c.ShouldBind(&propagationpolicyRequest); err != nil { | ||
common.Fail(c, err) | ||
return | ||
} | ||
|
||
var err error | ||
karmadaClient := client.InClusterKarmadaClient() | ||
if propagationpolicyRequest.IsClusterScope { | ||
clusterPropagationPolicy := v1alpha1.ClusterPropagationPolicy{} | ||
if err = yaml.Unmarshal([]byte(propagationpolicyRequest.PropagationData), &clusterPropagationPolicy); err != nil { | ||
klog.ErrorS(err, "Failed to unmarshal ClusterPropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
_, err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Create(ctx, &clusterPropagationPolicy, metav1.CreateOptions{}) | ||
} else { | ||
propagationPolicy := v1alpha1.PropagationPolicy{} | ||
if err = yaml.Unmarshal([]byte(propagationpolicyRequest.PropagationData), &propagationPolicy); err != nil { | ||
klog.ErrorS(err, "Failed to unmarshal PropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
_, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(propagationpolicyRequest.Namespace).Create(ctx, &propagationPolicy, metav1.CreateOptions{}) | ||
} | ||
if err != nil { | ||
klog.ErrorS(err, "Failed to create PropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
common.Success(c, "ok") | ||
} | ||
|
||
func handlePutClusterPropagationPolicy(c *gin.Context) { | ||
ctx := context.Context(c) | ||
propagationpolicyRequest := new(v1.PutPropagationPolicyRequest) | ||
if err := c.ShouldBind(&propagationpolicyRequest); err != nil { | ||
common.Fail(c, err) | ||
return | ||
} | ||
var err error | ||
karmadaClient := client.InClusterKarmadaClient() | ||
// todo check pp exist | ||
if propagationpolicyRequest.IsClusterScope { | ||
clusterPropagationPolicy := v1alpha1.ClusterPropagationPolicy{} | ||
if err = yaml.Unmarshal([]byte(propagationpolicyRequest.PropagationData), &clusterPropagationPolicy); err != nil { | ||
klog.ErrorS(err, "Failed to unmarshal ClusterPropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
_, err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Update(ctx, &clusterPropagationPolicy, metav1.UpdateOptions{}) | ||
} else { | ||
propagationPolicy := v1alpha1.PropagationPolicy{} | ||
if err = yaml.Unmarshal([]byte(propagationpolicyRequest.PropagationData), &propagationPolicy); err != nil { | ||
klog.ErrorS(err, "Failed to unmarshal PropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
var oldPropagationPolicy *v1alpha1.PropagationPolicy | ||
oldPropagationPolicy, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(propagationpolicyRequest.Namespace).Get(ctx, propagationpolicyRequest.Name, metav1.GetOptions{}) | ||
if err == nil { | ||
// only spec can be updated | ||
propagationPolicy.TypeMeta = oldPropagationPolicy.TypeMeta | ||
propagationPolicy.ObjectMeta = oldPropagationPolicy.ObjectMeta | ||
_, err = karmadaClient.PolicyV1alpha1().PropagationPolicies(propagationpolicyRequest.Namespace).Update(ctx, &propagationPolicy, metav1.UpdateOptions{}) | ||
} | ||
} | ||
if err != nil { | ||
klog.ErrorS(err, "Failed to update PropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
common.Success(c, "ok") | ||
} | ||
func handleDeleteClusterPropagationPolicy(c *gin.Context) { | ||
ctx := context.Context(c) | ||
propagationpolicyRequest := new(v1.DeletePropagationPolicyRequest) | ||
if err := c.ShouldBind(&propagationpolicyRequest); err != nil { | ||
common.Fail(c, err) | ||
return | ||
} | ||
var err error | ||
karmadaClient := client.InClusterKarmadaClient() | ||
if propagationpolicyRequest.IsClusterScope { | ||
err = karmadaClient.PolicyV1alpha1().ClusterPropagationPolicies().Delete(ctx, propagationpolicyRequest.Name, metav1.DeleteOptions{}) | ||
if err != nil { | ||
klog.ErrorS(err, "Failed to delete PropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
} else { | ||
err = karmadaClient.PolicyV1alpha1().PropagationPolicies(propagationpolicyRequest.Namespace).Delete(ctx, propagationpolicyRequest.Name, metav1.DeleteOptions{}) | ||
if err != nil { | ||
klog.ErrorS(err, "Failed to delete PropagationPolicy") | ||
common.Fail(c, err) | ||
return | ||
} | ||
err = retry.OnError( | ||
retry.DefaultRetry, | ||
func(err error) bool { | ||
return errors.IsNotFound(err) | ||
}, | ||
func() error { | ||
_, getErr := karmadaClient.PolicyV1alpha1().PropagationPolicies(propagationpolicyRequest.Namespace).Get(ctx, propagationpolicyRequest.Name, metav1.GetOptions{}) | ||
return getErr | ||
}) | ||
} | ||
|
||
common.Success(c, "ok") | ||
} | ||
|
||
func init() { | ||
r := router.V1() | ||
r.GET("/clusterpropagationpolicy", handleGetClusterPropagationPolicyList) | ||
r.GET("/clusterpropagationpolicy/:clusterPropagationPolicyName", handleGetClusterPropagationPolicyDetail) | ||
r.POST("/clusterpropagationpolicy", handlePostClusterPropagationPolicy) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package clusterpropagationpolicy | ||
|
||
import ( | ||
"github.com/karmada-io/dashboard/pkg/dataselect" | ||
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" | ||
) | ||
|
||
type ClusterPropagationPolicyCell v1alpha1.ClusterPropagationPolicy | ||
|
||
func (self ClusterPropagationPolicyCell) GetProperty(name dataselect.PropertyName) dataselect.ComparableValue { | ||
switch name { | ||
case dataselect.NameProperty: | ||
return dataselect.StdComparableString(self.ObjectMeta.Name) | ||
case dataselect.CreationTimestampProperty: | ||
return dataselect.StdComparableTime(self.ObjectMeta.CreationTimestamp.Time) | ||
default: | ||
// if name is not supported then just return a constant dummy value, sort will have no effect. | ||
return nil | ||
} | ||
} | ||
|
||
func toCells(std []v1alpha1.ClusterPropagationPolicy) []dataselect.DataCell { | ||
cells := make([]dataselect.DataCell, len(std)) | ||
for i := range std { | ||
cells[i] = ClusterPropagationPolicyCell(std[i]) | ||
} | ||
return cells | ||
} | ||
|
||
func fromCells(cells []dataselect.DataCell) []v1alpha1.ClusterPropagationPolicy { | ||
std := make([]v1alpha1.ClusterPropagationPolicy, len(cells)) | ||
for i := range std { | ||
std[i] = v1alpha1.ClusterPropagationPolicy(cells[i].(ClusterPropagationPolicyCell)) | ||
} | ||
return std | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package clusterpropagationpolicy | ||
|
||
import ( | ||
"context" | ||
"github.com/karmada-io/dashboard/pkg/common/errors" | ||
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" | ||
karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" | ||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
type ClusterPropagationPolicyDetail struct { | ||
// Extends list item structure. | ||
ClusterPropagationPolicy `json:",inline"` | ||
|
||
// List of non-critical errors, that occurred during resource retrieval. | ||
Errors []error `json:"errors"` | ||
} | ||
|
||
// GetClusterPropagationPolicyDetail gets clusterPropagationPolicy details. | ||
func GetClusterPropagationPolicyDetail(client karmadaclientset.Interface, name string) (*ClusterPropagationPolicyDetail, error) { | ||
propagationpolicyData, err := client.PolicyV1alpha1().ClusterPropagationPolicies().Get(context.TODO(), name, metaV1.GetOptions{}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
nonCriticalErrors, criticalError := errors.ExtractErrors(err) | ||
if criticalError != nil { | ||
return nil, criticalError | ||
} | ||
|
||
propagationpolicy := toPropagationPolicyDetail(propagationpolicyData, nonCriticalErrors) | ||
return &propagationpolicy, nil | ||
} | ||
|
||
func toPropagationPolicyDetail(clusterPropagationpolicy *v1alpha1.ClusterPropagationPolicy, nonCriticalErrors []error) ClusterPropagationPolicyDetail { | ||
return ClusterPropagationPolicyDetail{ | ||
ClusterPropagationPolicy: toClusterPropagationPolicy(clusterPropagationpolicy), | ||
Errors: nonCriticalErrors, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package clusterpropagationpolicy | ||
|
||
import ( | ||
"context" | ||
"github.com/karmada-io/dashboard/pkg/common/errors" | ||
"github.com/karmada-io/dashboard/pkg/common/helpers" | ||
"github.com/karmada-io/dashboard/pkg/common/types" | ||
"github.com/karmada-io/dashboard/pkg/dataselect" | ||
"github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1" | ||
karmadaclientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned" | ||
) | ||
|
||
// ClusterPropagationPolicyList contains a list of propagation in the karmada control-plane. | ||
type ClusterPropagationPolicyList struct { | ||
ListMeta types.ListMeta `json:"listMeta"` | ||
|
||
// Unordered list of PropagationPolicies. | ||
ClusterPropagationPolicies []ClusterPropagationPolicy `json:"clusterPropagationPolicies"` | ||
|
||
// List of non-critical errors, that occurred during resource retrieval. | ||
Errors []error `json:"errors"` | ||
} | ||
|
||
type ClusterPropagationPolicy struct { | ||
ObjectMeta types.ObjectMeta `json:"objectMeta"` | ||
TypeMeta types.TypeMeta `json:"typeMeta"` | ||
SchedulerName string `json:"schedulerName"` | ||
ClusterAffinity *v1alpha1.ClusterAffinity `json:"clusterAffinity"` | ||
ResourceSelectors []v1alpha1.ResourceSelector `json:"resourceSelectors"` | ||
} | ||
|
||
// GetClusterPropagationPolicyList returns a list of all propagations in the karmada control-plance. | ||
func GetClusterPropagationPolicyList(client karmadaclientset.Interface, dsQuery *dataselect.DataSelectQuery) (*ClusterPropagationPolicyList, error) { | ||
clusterPropagationPolicies, err := client.PolicyV1alpha1().ClusterPropagationPolicies().List(context.TODO(), helpers.ListEverything) | ||
nonCriticalErrors, criticalError := errors.ExtractErrors(err) | ||
if criticalError != nil { | ||
return nil, criticalError | ||
} | ||
|
||
return toClusterPropagationPolicyList(clusterPropagationPolicies.Items, nonCriticalErrors, dsQuery), nil | ||
} | ||
|
||
func toClusterPropagationPolicyList(clusterPropagationPolicies []v1alpha1.ClusterPropagationPolicy, nonCriticalErrors []error, dsQuery *dataselect.DataSelectQuery) *ClusterPropagationPolicyList { | ||
propagationpolicyList := &ClusterPropagationPolicyList{ | ||
ClusterPropagationPolicies: make([]ClusterPropagationPolicy, 0), | ||
ListMeta: types.ListMeta{TotalItems: len(clusterPropagationPolicies)}, | ||
} | ||
clusterPropagationPolicyCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(clusterPropagationPolicies), dsQuery) | ||
clusterPropagationPolicies = fromCells(clusterPropagationPolicyCells) | ||
propagationpolicyList.ListMeta = types.ListMeta{TotalItems: filteredTotal} | ||
propagationpolicyList.Errors = nonCriticalErrors | ||
|
||
for _, clusterPropagationPolicy := range clusterPropagationPolicies { | ||
clusterPP := toClusterPropagationPolicy(&clusterPropagationPolicy) | ||
propagationpolicyList.ClusterPropagationPolicies = append(propagationpolicyList.ClusterPropagationPolicies, clusterPP) | ||
} | ||
return propagationpolicyList | ||
} | ||
|
||
func toClusterPropagationPolicy(propagationpolicy *v1alpha1.ClusterPropagationPolicy) ClusterPropagationPolicy { | ||
return ClusterPropagationPolicy{ | ||
ObjectMeta: types.NewObjectMeta(propagationpolicy.ObjectMeta), | ||
TypeMeta: types.NewTypeMeta(types.ResourceKindClusterPropagationPolicy), | ||
SchedulerName: propagationpolicy.Spec.SchedulerName, | ||
ClusterAffinity: propagationpolicy.Spec.Placement.ClusterAffinity, | ||
} | ||
} |