Files
kubevela/pkg/policy/envbinding/placement.go
Somefive b622cbdb7f Feat: ResourceTracker new architecture (#2849)
* Feat: new rt

Signed-off-by: Yin Da <yd219913@alibaba-inc.com>

* Fix: add publish version

Signed-off-by: Yin Da <yd219913@alibaba-inc.com>
2021-12-10 15:00:03 +08:00

126 lines
3.9 KiB
Go

/*
Copyright 2021 The KubeVela 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 envbinding
import (
"encoding/json"
"k8s.io/apimachinery/pkg/runtime"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
)
// ReadPlacementDecisions read placement decisions from application status, return (decisions, if decision is made, error)
func ReadPlacementDecisions(app *v1beta1.Application, policyName string, envName string) ([]v1alpha1.PlacementDecision, bool, error) {
envBindingStatus, err := GetEnvBindingPolicyStatus(app, policyName)
if err != nil || envBindingStatus == nil {
return nil, false, err
}
for _, envStatus := range envBindingStatus.Envs {
if envStatus.Env == envName {
return envStatus.Placements, true, nil
}
}
return nil, false, nil
}
// updateClusterConnections update cluster connection in envbinding status with decisions
func updateClusterConnections(status *v1alpha1.EnvBindingStatus, decisions []v1alpha1.PlacementDecision, app *v1beta1.Application) {
var currentRev string
if app.Status.LatestRevision != nil {
currentRev = app.Status.LatestRevision.Name
}
clusterMap := map[string]bool{}
for _, decision := range decisions {
clusterMap[decision.Cluster] = true
}
for clusterName := range clusterMap {
exists := false
for idx, conn := range status.ClusterConnections {
if conn.ClusterName == clusterName {
exists = true
status.ClusterConnections[idx].LastActiveRevision = currentRev
break
}
}
if !exists {
status.ClusterConnections = append(status.ClusterConnections, v1alpha1.ClusterConnection{
ClusterName: clusterName,
LastActiveRevision: currentRev,
})
}
}
}
// WritePlacementDecisions write placement decisions into application status
func WritePlacementDecisions(app *v1beta1.Application, policyName string, envName string, decisions []v1alpha1.PlacementDecision) error {
statusExists := false
for idx, policyStatus := range app.Status.PolicyStatus {
if policyStatus.Name == policyName && policyStatus.Type == v1alpha1.EnvBindingPolicyType {
envBindingStatus := &v1alpha1.EnvBindingStatus{}
err := json.Unmarshal(policyStatus.Status.Raw, envBindingStatus)
if err != nil {
return err
}
insert := true
for _idx, envStatus := range envBindingStatus.Envs {
if envStatus.Env == envName {
// TODO gc
envBindingStatus.Envs[_idx].Placements = decisions
insert = false
break
}
}
if insert {
envBindingStatus.Envs = append(envBindingStatus.Envs, v1alpha1.EnvStatus{
Env: envName,
Placements: decisions,
})
}
updateClusterConnections(envBindingStatus, decisions, app)
bs, err := json.Marshal(envBindingStatus)
if err != nil {
return err
}
app.Status.PolicyStatus[idx].Status = &runtime.RawExtension{Raw: bs}
statusExists = true
break
}
}
if !statusExists {
envBindingStatus := &v1alpha1.EnvBindingStatus{
Envs: []v1alpha1.EnvStatus{{
Env: envName,
Placements: decisions,
}},
}
updateClusterConnections(envBindingStatus, decisions, app)
bs, err := json.Marshal(envBindingStatus)
if err != nil {
return err
}
app.Status.PolicyStatus = append(app.Status.PolicyStatus, common.PolicyStatus{
Name: policyName,
Type: v1alpha1.EnvBindingPolicyType,
Status: &runtime.RawExtension{Raw: bs},
})
}
return nil
}