Files
sealos/test/testdata/api/kubernetes.go
T
晓杰 fd8ae0dfd6 feat: refactor metering ,support Third-party resource access and idempotent (#2258)
* feat:design metering、podresource、resource api type
* metering watch user ns and create
* feat:add e2e test about metering watch ns
* feat:metering watch extensionResourcePrice
* feat:pod-controller create resurce CR logic
* feat:metering watch Resource create by resource-Controller and update Metering
* feat:metering create AccountBalance and account will watch it and deduction balancde
* feat:add infra calculate test
* feat:add deploy.yaml and temporary ci
* feat:change account ns to sealos-system
* fix:update resourceName
* feat:add deduction info to account chargelist
* fix:payment error
* fix:update resource name
* Modify inappropriate places in the code by github Comment

Signed-off-by: 晓杰 <2561589453@qq.com>
2022-12-29 14:43:06 +08:00

316 lines
7.8 KiB
Go

// Copyright © 2022 sealos.
//
// 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 api
import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"time"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/runtime"
userv1 "github.com/labring/sealos/controllers/user/api/v1"
"gopkg.in/yaml.v3"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
// GetDefaultKubernetesClient returns a kubernetes client
func GetDefaultKubernetesClient() *kubernetes.Clientset {
kubeconfig := GetDefaultKubeConfigPath()
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err.Error())
}
// create the client
client, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
return client
}
func GetDefaultKubeConfigPath() string {
// get the value of the environment variable KUBE_CONFIG_FILE
kubeconfig := os.Getenv("KUBE_CONFIG_FILE")
if kubeconfig == "" {
// if KUBECONFIG is not set, use the default location
kubeconfig = filepath.Join(homedir.HomeDir(), ".kube", "config")
}
return kubeconfig
}
func GetDefaultDynamicClient() dynamic.Interface {
kubeconfig := GetDefaultKubeConfigPath()
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err.Error())
}
// create the client
client, err := dynamic.NewForConfig(config)
if err != nil {
panic(err.Error())
}
return client
}
func GetNodeAddress() string {
// get the address from env variable first: NODE_ADDRESS
nodeAddress := os.Getenv("NODE_ADDRESS")
if nodeAddress != "" {
return nodeAddress
}
client := GetDefaultKubernetesClient()
nodes, err := client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
return nodes.Items[0].Status.Addresses[0].Address
}
func CreateNamespace(client *kubernetes.Clientset, name string) *v1.Namespace {
ns := &v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Annotations: map[string]string{
userv1.UserAnnotationOwnerKey: name[3:],
},
},
}
result, err := client.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
if err != nil {
panic(err.Error())
}
return result
}
func EnsureDeleteNamespace(name string, times int) error {
client := GetDefaultKubernetesClient()
_, err := client.CoreV1().Namespaces().Get(context.TODO(), name, metav1.GetOptions{})
if err == nil {
DeleteNamespace(name)
}
for i := 0; i < times; i++ {
_, err := client.CoreV1().Namespaces().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
break
}
time.Sleep(time.Second)
}
return nil
}
func GetObject(namespace string, name string, gvr schema.GroupVersionResource, out interface{}) error {
client := GetDefaultDynamicClient()
obj, err := client.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return err
}
err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, out)
if err != nil {
return err
}
return nil
}
func KubeUpdateStatus(name, namespace, statusYaml string, gvr schema.GroupVersionResource) error {
client := GetDefaultDynamicClient()
user, err := client.Resource(gvr).Namespace(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return err
}
status := make(map[string]interface{})
err = yaml.Unmarshal([]byte(statusYaml), &status)
if err != nil {
return err
}
user.Object["status"] = status
_, err = client.Resource(gvr).Namespace(namespace).UpdateStatus(context.TODO(), user, metav1.UpdateOptions{})
if err != nil {
return err
}
return nil
}
func Exec(command string) (string, error) {
cmd := exec.Command("sh", "-c", command)
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
return stderr.String(), err
}
return stdout.String(), nil
}
func KubeApplyFromTemplate(yaml string, params map[string]string) (string, error) {
out := os.Expand(yaml, func(k string) string { return params[k] })
return KubeApply(out)
}
func CreateCRD(namespace string, name string, yaml string) {
MustKubeApplyFromTemplate(yaml, map[string]string{
"namespace": namespace,
"name": name,
})
}
func MustKubeApplyFromTemplate(yaml string, params map[string]string) {
_, err := KubeApplyFromTemplate(yaml, params)
if err != nil {
panic(err)
}
}
func DeleteCRD(namespace string, name string, yaml string) error {
_, err := KubeDeleteFromTemplate(yaml, map[string]string{
"namespace": namespace,
"name": name,
})
if err != nil {
return err
}
return nil
}
func KubeDeleteFromTemplate(yaml string, params map[string]string) (string, error) {
out := os.Expand(yaml, func(k string) string { return params[k] })
return KubeDelete(out)
}
func MustKubeDeleteFromTemplate(yaml string, params map[string]string) {
_, err := KubeDeleteFromTemplate(yaml, params)
if err != nil {
panic(err)
}
}
func KubeApply(yaml string) (string, error) {
cmd := `kubectl apply -f - <<EOF` + yaml + `EOF`
out, err := Exec(cmd)
if err != nil {
return out, err
}
return out, nil
}
func MustKubeApply(yaml string) {
_, err := KubeApply(yaml)
if err != nil {
panic(err)
}
}
func KubeDelete(yaml string) (string, error) {
cmd := `kubectl delete -f - <<EOF` + yaml + `EOF`
out, err := Exec(cmd)
if err != nil {
return out, err
}
return out, nil
}
func MustKubeDelete(yaml string) {
_, err := KubeDelete(yaml)
if err != nil {
panic(err)
}
}
func KubeWaitForDeleted(namespace string, groupResourceName string, timeout string) (string, error) {
cmd := fmt.Sprintf(`kubectl wait --for=delete --timeout=%s %s -n %s`, timeout, groupResourceName, namespace)
out, err := Exec(cmd)
if err != nil {
return out, err
}
return out, nil
}
func MustKubeWaitForDeleted(namespace string, groupResourceName string, timeout string) {
_, err := KubeWaitForDeleted(namespace, groupResourceName, timeout)
if err != nil {
panic(err.Error())
}
}
func KubeWaitForCondition(namespace string, groupResourceName string, condition string, timeout string) (string, error) {
cmd := fmt.Sprintf(`kubectl wait --for=condition=%s --timeout=%s %s -n %s`, condition, timeout, groupResourceName, namespace)
out, err := Exec(cmd)
if err != nil {
return out, err
}
return out, nil
}
func MustKubeWaitForCondition(namespace string, groupResourceName string, condition string, timeout string) {
_, err := KubeWaitForCondition(namespace, groupResourceName, condition, timeout)
if err != nil {
panic(err.Error())
}
}
func KubeWaitForReady(namespace string, groupResourceName string, timeout string) (string, error) {
out, err := KubeWaitForCondition(namespace, groupResourceName, "ready", timeout)
if err != nil {
return out, err
}
return out, nil
}
func MustKubeWaitForReady(namespace string, groupResourceName string, timeout string) {
_, err := KubeWaitForReady(namespace, groupResourceName, timeout)
if err != nil {
panic(err.Error())
}
}
func WaitForReady(fn func(args ...interface{}) bool, times int) error {
for i := 1; i <= times; i++ {
if fn() {
return nil
}
time.Sleep(time.Second)
}
return errors.New("timeout")
}