func DeleteCertificateV1Beta1Resources(client kubernetes.Interface, resources, namespace, name string) error {
	err := client.CertificatesV1beta1().CertificateSigningRequests().Delete(context.Background(), name, metav1.DeleteOptions{})
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	return nil
}
DeleteCertificateV1Beta1Resources deletes resources within group CertificateV1Beta1.
package installbase
import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"
	"github.com/megaease/easemeshctl/cmd/common"
	admissionregv1 "k8s.io/api/admissionregistration/v1"
	appsV1 "k8s.io/api/apps/v1"
	v1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
	apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)
var (
	scheme         = runtime.NewScheme()
	codecs         = serializer.NewCodecFactory(scheme)
	parameterCodec = runtime.NewParameterCodec(scheme)
	encoder = unstructured.NewJSONFallbackEncoder(codecs.LegacyCodec(scheme.PrioritizedVersionsAllGroups()...))
	metadataAccessor = meta.NewAccessor()
)
type (
	createResourceFunc func() error
	getResourceRunc    func() (runtime.Object, error)
	updateResourceFunc func() error
	PredictFunc func(interface{}) bool
	PodStatus struct {
		Name            string
		ReadyContainer  int
		ExpectContainer int
		Status          string
		Restarts        int
	}
	deleteResourceFunc func(kubernetes.Interface, string, string, string) error
	ListPodFunc func(kubernetes.Interface, string) []PodStatus
)
func NewKubernetesClient() (kubernetes.Interface, error) {
	config, err := clientcmd.BuildConfigFromFlags("", DefaultKubernetesConfigPath)
	if err != nil {
		return nil, err
	}
	kubeClient, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return kubeClient, nil
}
func NewKubernetesAPIExtensionsClient() (apiextensions.Interface, error) {
	config, err := clientcmd.BuildConfigFromFlags("", DefaultKubernetesConfigPath)
	if err != nil {
		return nil, err
	}
	clientset, err := apiextensions.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return clientset, nil
}
func requestContext() context.Context     { return context.TODO() }
func createOptions() metav1.CreateOptions { return metav1.CreateOptions{} }
func getOptions() metav1.GetOptions       { return metav1.GetOptions{} }
func updateOptions() metav1.UpdateOptions { return metav1.UpdateOptions{} }
func adaptReplaceObject(old, new runtime.Object) error {
	oldAnnots, err := metadataAccessor.Annotations(old)
	if err != nil {
		return err
	}
	delete(oldAnnots, v1.LastAppliedConfigAnnotation)
	metadataAccessor.SetAnnotations(old, oldAnnots)
	lastConfig, err := json.Marshal(old)
	if err != nil {
		return err
	}
	newAnnots, err := metadataAccessor.Annotations(new)
	if err != nil {
		return err
	}
	if newAnnots == nil {
		newAnnots = make(map[string]string)
	}
	newAnnots[v1.LastAppliedConfigAnnotation] = string(lastConfig)
	err = metadataAccessor.SetAnnotations(new, newAnnots)
	if err != nil {
		return err
	}
	oldResourceVersion, err := metadataAccessor.ResourceVersion(old)
	if err == nil {
		metadataAccessor.SetResourceVersion(new, oldResourceVersion)
	}
	return nil
}
func deployResource(createFn createResourceFunc, updateFn updateResourceFunc) error {
	err := createFn()
	if err == nil {
		return nil
	}
	if !errors.IsAlreadyExists(err) {
		return err
	}
	return updateFn()
}
func DeployNamespace(namespace *v1.Namespace, clientSet kubernetes.Interface) error {
	createFn := func() error {
		_, err := clientSet.CoreV1().Namespaces().
			Create(requestContext(), namespace, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.CoreV1().Namespaces().
			Get(requestContext(), namespace.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, namespace)
		if err != nil {
			return err
		}
		_, err = clientSet.CoreV1().Namespaces().
			Update(requestContext(), namespace, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployDeployment(deployment *appsV1.Deployment, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.AppsV1().Deployments(namespace).
			Create(requestContext(), deployment, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.AppsV1().Deployments(namespace).
			Get(requestContext(), deployment.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, deployment)
		if err != nil {
			return err
		}
		_, err = clientSet.AppsV1().Deployments(namespace).
			Update(requestContext(), deployment, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployStatefulset(statefulset *appsV1.StatefulSet, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.AppsV1().StatefulSets(namespace).
			Create(requestContext(), statefulset, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.AppsV1().StatefulSets(namespace).
			Get(requestContext(), statefulset.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, statefulset)
		if err != nil {
			return err
		}
		_, err = clientSet.AppsV1().StatefulSets(namespace).
			Update(requestContext(), statefulset, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployService(service *v1.Service, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.CoreV1().Services(namespace).
			Create(requestContext(), service, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.CoreV1().Services(namespace).
			Get(requestContext(), service.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, service)
		if err != nil {
			return err
		}
		service.Spec.ClusterIP = oldObject.Spec.ClusterIP
		service.Spec.ClusterIPs = oldObject.Spec.ClusterIPs
		_, err = clientSet.CoreV1().Services(namespace).
			Update(requestContext(), service, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployConfigMap(configMap *v1.ConfigMap, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.CoreV1().ConfigMaps(namespace).
			Create(requestContext(), configMap, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.CoreV1().ConfigMaps(namespace).
			Get(requestContext(), configMap.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, configMap)
		if err != nil {
			return err
		}
		_, err = clientSet.CoreV1().ConfigMaps(namespace).
			Update(requestContext(), configMap, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeploySecret(secret *v1.Secret, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.CoreV1().Secrets(namespace).
			Create(requestContext(), secret, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.CoreV1().Secrets(namespace).
			Get(requestContext(), secret.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, secret)
		if err != nil {
			return err
		}
		_, err = clientSet.CoreV1().Secrets(namespace).
			Update(requestContext(), secret, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployMutatingWebhookConfig(mutatingWebhookConfig *admissionregv1.MutatingWebhookConfiguration, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.AdmissionregistrationV1().MutatingWebhookConfigurations().
			Create(requestContext(), mutatingWebhookConfig, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.AdmissionregistrationV1().MutatingWebhookConfigurations().
			Get(requestContext(), mutatingWebhookConfig.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, mutatingWebhookConfig)
		if err != nil {
			return err
		}
		_, err = clientSet.AdmissionregistrationV1().MutatingWebhookConfigurations().
			Update(requestContext(), mutatingWebhookConfig, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func ListPersistentVolume(clientSet kubernetes.Interface) (*v1.PersistentVolumeList, error) {
	return clientSet.CoreV1().PersistentVolumes().List(requestContext(), metav1.ListOptions{})
}
func DeployRole(role *rbacv1.Role, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.RbacV1().Roles(namespace).
			Create(requestContext(), role, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.RbacV1().Roles(namespace).
			Get(requestContext(), role.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, role)
		if err != nil {
			return err
		}
		_, err = clientSet.RbacV1().Roles(namespace).
			Update(requestContext(), role, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployRoleBinding(roleBinding *rbacv1.RoleBinding, clientSet kubernetes.Interface, namespace string) error {
	createFn := func() error {
		_, err := clientSet.RbacV1().RoleBindings(namespace).
			Create(requestContext(), roleBinding, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.RbacV1().RoleBindings(namespace).
			Get(requestContext(), roleBinding.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, roleBinding)
		if err != nil {
			return err
		}
		_, err = clientSet.RbacV1().RoleBindings(namespace).
			Update(requestContext(), roleBinding, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployClusterRole(clusterRole *rbacv1.ClusterRole, clientSet kubernetes.Interface) error {
	createFn := func() error {
		_, err := clientSet.RbacV1().ClusterRoles().
			Create(requestContext(), clusterRole, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.RbacV1().ClusterRoles().
			Get(requestContext(), clusterRole.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, clusterRole)
		if err != nil {
			return err
		}
		_, err = clientSet.RbacV1().ClusterRoles().
			Update(requestContext(), clusterRole, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployClusterRoleBinding(clusterRoleBinding *rbacv1.ClusterRoleBinding, clientSet kubernetes.Interface) error {
	createFn := func() error {
		_, err := clientSet.RbacV1().ClusterRoleBindings().
			Create(requestContext(), clusterRoleBinding, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.RbacV1().ClusterRoleBindings().
			Get(requestContext(), clusterRoleBinding.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, clusterRoleBinding)
		if err != nil {
			return err
		}
		_, err = clientSet.RbacV1().ClusterRoleBindings().
			Update(requestContext(), clusterRoleBinding, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func DeployCustomResourceDefinition(crd *apiextensionsv1.CustomResourceDefinition, clientSet apiextensions.Interface) error {
	createFn := func() error {
		_, err := clientSet.ApiextensionsV1().CustomResourceDefinitions().
			Create(requestContext(), crd, createOptions())
		return err
	}
	updateFn := func() error {
		oldObject, err := clientSet.ApiextensionsV1().CustomResourceDefinitions().
			Get(requestContext(), crd.Name, getOptions())
		if err != nil {
			return err
		}
		err = adaptReplaceObject(oldObject, crd)
		if err != nil {
			return err
		}
		_, err = clientSet.ApiextensionsV1().CustomResourceDefinitions().
			Update(requestContext(), crd, updateOptions())
		return err
	}
	return deployResource(createFn, updateFn)
}
func StatefulsetReadyPredict(object interface{}) (ready bool) {
	statefulset, ok := object.(*appsV1.StatefulSet)
	if !ok {
		return
	}
	return statefulset.Status.ReadyReplicas == *statefulset.Spec.Replicas
}
func DeploymentReadyPredict(object interface{}) (ready bool) {
	deploy, ok := object.(*appsV1.Deployment)
	if !ok {
		return
	}
	return deploy.Status.ReadyReplicas == *deploy.Spec.Replicas
}
func CheckStatefulsetResourceStatus(client kubernetes.Interface, namespace, resourceName string, predict PredictFunc) (bool, error) {
	statefulset, err := client.AppsV1().StatefulSets(namespace).Get(requestContext(), resourceName, metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			return false, nil
		}
		return false, err
	}
	return predict(statefulset), nil
}
func CheckDeploymentResourceStatus(client kubernetes.Interface, namespace, name string, predict PredictFunc) (bool, error) {
	deploy, err := client.AppsV1().Deployments(namespace).Get(requestContext(), name, metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			return false, nil
		}
		return false, err
	}
	return predict(deploy), nil
}
func GetMeshControlPlaneEndpoints(client kubernetes.Interface, namespace, resourceName, portName string) ([]string, error) {
	service, err := client.CoreV1().Services(namespace).Get(requestContext(), resourceName, metav1.GetOptions{})
	if err != nil {
		return nil, err
	}
	nodes, err := client.CoreV1().Nodes().List(requestContext(), metav1.ListOptions{})
	if err != nil {
		return nil, err
	}
	var nodePort int32
	for _, p := range service.Spec.Ports {
		if p.Name == portName {
			nodePort = p.NodePort
			break
		}
	}
	entrypoints := []string{}
	for _, n := range nodes.Items {
		for _, i := range n.Status.Addresses {
			if i.Type == v1.NodeInternalIP {
				entrypoints = append(entrypoints, "http://"+i.Address+":"+strconv.Itoa(int(nodePort)))
			}
		}
	}
	return entrypoints, nil
}
func BatchDeployResources(ctx *StageContext, installFuncs []InstallFunc) error {
	for _, fn := range installFuncs {
		err := fn.Deploy(ctx)
		if err != nil {
			return err
		}
	}
	return nil
}
func DeleteStatefulsetResource(client kubernetes.Interface, resource, namespace, name string) error {
	err := client.AppsV1().StatefulSets(namespace).Delete(context.Background(), name, metav1.DeleteOptions{})
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	return nil
}
func DeleteAppsV1Resource(client kubernetes.Interface, resource, namespace, name string) error {
	err := client.AppsV1().RESTClient().Delete().Resource(resource).Namespace(namespace).Name(name).Do(context.Background()).Error()
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	return nil
}
func DeleteCoreV1Resource(client kubernetes.Interface, resource, namespace, name string) error {
	err := client.CoreV1().RESTClient().Delete().Resource(resource).Namespace(namespace).Name(name).Do(context.Background()).Error()
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	return nil
}
func DeleteRbacV1Resources(client kubernetes.Interface, resources, namespace, name string) error {
	err := client.RbacV1().RESTClient().Delete().Resource(resources).Namespace(namespace).Name(name).Do(context.Background()).Error()
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	return nil
}
func DeleteAdmissionregV1Resources(client kubernetes.Interface, resources, namespace, name string) error {
	err := client.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(requestContext(), name, metav1.DeleteOptions{})
	if err != nil && !errors.IsNotFound(err) {
		return err
	}
	return nil
}