k3s/vendor/github.com/rancher/wrangler/pkg/apply/reconcilers.go
2019-12-15 23:28:25 -07:00

131 lines
3.0 KiB
Go

package apply
import (
"encoding/json"
"fmt"
"reflect"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var (
defaultReconcilers = map[schema.GroupVersionKind]Reconciler{
v1.SchemeGroupVersion.WithKind("Service"): reconcileService,
batchv1.SchemeGroupVersion.WithKind("Job"): reconcileJob,
appsv1.SchemeGroupVersion.WithKind("Deployment"): reconcileDeployment,
appsv1.SchemeGroupVersion.WithKind("DaemonSet"): reconcileDaemonSet,
}
)
func reconcileDaemonSet(oldObj, newObj runtime.Object) (bool, error) {
oldSvc, ok := oldObj.(*appsv1.DaemonSet)
if !ok {
oldSvc = &appsv1.DaemonSet{}
if err := convertObj(oldObj, oldSvc); err != nil {
return false, err
}
}
newSvc, ok := newObj.(*appsv1.DaemonSet)
if !ok {
newSvc = &appsv1.DaemonSet{}
if err := convertObj(newObj, newSvc); err != nil {
return false, err
}
}
if !equality.Semantic.DeepEqual(oldSvc.Spec.Selector, newSvc.Spec.Selector) {
return false, ErrReplace
}
return false, nil
}
func reconcileDeployment(oldObj, newObj runtime.Object) (bool, error) {
oldSvc, ok := oldObj.(*appsv1.Deployment)
if !ok {
oldSvc = &appsv1.Deployment{}
if err := convertObj(oldObj, oldSvc); err != nil {
return false, err
}
}
newSvc, ok := newObj.(*appsv1.Deployment)
if !ok {
newSvc = &appsv1.Deployment{}
if err := convertObj(newObj, newSvc); err != nil {
return false, err
}
}
if !equality.Semantic.DeepEqual(oldSvc.Spec.Selector, newSvc.Spec.Selector) {
return false, ErrReplace
}
return false, nil
}
func reconcileService(oldObj, newObj runtime.Object) (bool, error) {
oldSvc, ok := oldObj.(*v1.Service)
if !ok {
oldSvc = &v1.Service{}
if err := convertObj(oldObj, oldSvc); err != nil {
return false, err
}
}
newSvc, ok := newObj.(*v1.Service)
if !ok {
newSvc = &v1.Service{}
if err := convertObj(newObj, newSvc); err != nil {
return false, err
}
}
if newSvc.Spec.Type != "" && oldSvc.Spec.Type != newSvc.Spec.Type {
return false, ErrReplace
}
return false, nil
}
func reconcileJob(oldObj, newObj runtime.Object) (bool, error) {
oldSvc, ok := oldObj.(*batchv1.Job)
if !ok {
oldSvc = &batchv1.Job{}
if err := convertObj(oldObj, oldSvc); err != nil {
return false, err
}
}
newSvc, ok := newObj.(*batchv1.Job)
if !ok {
newSvc = &batchv1.Job{}
if err := convertObj(newObj, newSvc); err != nil {
return false, err
}
}
if !equality.Semantic.DeepEqual(oldSvc.Spec.Template, newSvc.Spec.Template) {
return false, ErrReplace
}
return false, nil
}
func convertObj(src interface{}, obj interface{}) error {
uObj, ok := src.(*unstructured.Unstructured)
if !ok {
return fmt.Errorf("expected unstructured but got %v", reflect.TypeOf(src))
}
bytes, err := uObj.MarshalJSON()
if err != nil {
return err
}
return json.Unmarshal(bytes, obj)
}