mirror of
https://github.com/truecharts/charts.git
synced 2026-07-18 23:11:41 -03:00
179 lines
6.3 KiB
Go
179 lines
6.3 KiB
Go
package kubectlcmds
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
"k8s.io/client-go/util/homedir"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/kustomize/api/krusty"
|
|
"sigs.k8s.io/kustomize/kyaml/filesys"
|
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
|
"sigs.k8s.io/yaml"
|
|
)
|
|
|
|
// getKubeClient initializes and returns a controller-runtime client.Client
|
|
func getKubeClient() (client.Client, error) {
|
|
log.Trace().Msg("Initializing Kubernetes client")
|
|
|
|
// Load kubeconfig from the default location
|
|
kubeconfig := filepath.Join(homedir.HomeDir(), ".kube", "config")
|
|
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to load kubeconfig")
|
|
return nil, fmt.Errorf("failed to load kubeconfig: %v", err)
|
|
}
|
|
|
|
// Create a controller-runtime client
|
|
c, err := client.New(config, client.Options{})
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to create Kubernetes client")
|
|
return nil, fmt.Errorf("failed to create Kubernetes client: %v", err)
|
|
}
|
|
|
|
log.Debug().Msg("Successfully initialized Kubernetes client")
|
|
return c, nil
|
|
}
|
|
|
|
// applyYAML applies the given YAML data to the Kubernetes cluster using the provided client
|
|
func applyYAML(k8sClient client.Client, yamlData []byte) error {
|
|
log.Trace().Msg("Applying YAML data to the Kubernetes cluster")
|
|
|
|
// Parse the YAML into KIO nodes
|
|
reader := kio.ByteReader{
|
|
Reader: bytes.NewReader(yamlData),
|
|
}
|
|
nodes, err := reader.Read()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to parse YAML")
|
|
return fmt.Errorf("failed to parse YAML: %v", err)
|
|
}
|
|
|
|
// Apply each node to the cluster
|
|
for _, node := range nodes {
|
|
obj := &unstructured.Unstructured{}
|
|
if err := yaml.Unmarshal([]byte(node.MustString()), obj); err != nil {
|
|
log.Error().Err(err).Msg("Failed to unmarshal node")
|
|
return fmt.Errorf("failed to unmarshal node: %v", err)
|
|
}
|
|
if err := k8sClient.Patch(context.TODO(), obj, client.Apply, client.FieldOwner("kustomize-controller")); err != nil {
|
|
log.Warn().Err(err).Msg("Failed to apply yaml object... trying again in 15 seconds...")
|
|
time.Sleep(15 * time.Second)
|
|
if err := k8sClient.Patch(context.TODO(), obj, client.Apply, client.FieldOwner("kustomize-controller")); err != nil {
|
|
log.Error().Err(err).Msg("Failed to apply object")
|
|
return fmt.Errorf("failed to apply object: %v", err)
|
|
}
|
|
}
|
|
log.Info().Msgf("Successfully applied object: %s of kind: %s in namespace: %s", obj.GetName(), obj.GetKind(), obj.GetNamespace())
|
|
}
|
|
|
|
log.Debug().Msg("YAML application completed")
|
|
return nil
|
|
}
|
|
|
|
// KubectlApply applies a YAML file to the Kubernetes cluster and filters the logs
|
|
func KubectlApply(ctx context.Context, filePath string) error {
|
|
log.Trace().Msgf("Applying YAML file at path: %s", filePath)
|
|
|
|
// Check if the file exists
|
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
log.Error().Err(err).Msgf("File does not exist: %s", filePath)
|
|
return fmt.Errorf("file does not exist: %s", filePath)
|
|
}
|
|
|
|
// Read the YAML file
|
|
yamlData, err := ioutil.ReadFile(filePath)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to read YAML file")
|
|
return fmt.Errorf("failed to read YAML file: %v", err)
|
|
}
|
|
|
|
// Initialize Kubernetes client
|
|
k8sClient, err := getKubeClient()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to initialize Kubernetes client")
|
|
return err
|
|
}
|
|
|
|
// Apply the YAML to the cluster
|
|
if err := applyYAML(k8sClient, yamlData); err != nil {
|
|
log.Error().Err(err).Msg("Failed to apply YAML")
|
|
return fmt.Errorf("failed to apply YAML: %v", err)
|
|
}
|
|
|
|
// Filter the logs
|
|
log.Info().Msg("KubectlApply operation completed")
|
|
|
|
return nil
|
|
}
|
|
|
|
// KubectlApplyKustomize applies a kustomize directory or file to the Kubernetes cluster and filters the logs
|
|
func KubectlApplyKustomize(ctx context.Context, filePath string) error {
|
|
log.Trace().Msgf("Applying Kustomize directory or file at path: %s", filePath)
|
|
|
|
// Check if the path exists
|
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
log.Error().Err(err).Msgf("Path does not exist: %s", filePath)
|
|
return fmt.Errorf("path does not exist: %s", filePath)
|
|
}
|
|
|
|
// Determine if the path is a directory or a file
|
|
fileInfo, err := os.Stat(filePath)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to stat path")
|
|
return fmt.Errorf("failed to stat path: %v", err)
|
|
}
|
|
|
|
var kustomizePath string
|
|
if fileInfo.IsDir() {
|
|
// If it's a directory, use it as the kustomize path
|
|
kustomizePath = filePath
|
|
log.Debug().Msgf("Using directory as kustomize path: %s", kustomizePath)
|
|
} else {
|
|
// If it's a file, use its directory as the kustomize path
|
|
kustomizePath = filepath.Dir(filePath)
|
|
log.Debug().Msgf("Using file's directory as kustomize path: %s", kustomizePath)
|
|
}
|
|
|
|
// Process kustomize to get the YAML output
|
|
fSys := filesys.MakeFsOnDisk()
|
|
k := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
|
resMap, err := k.Run(fSys, kustomizePath)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to run kustomize")
|
|
return fmt.Errorf("failed to run kustomize: %v", err)
|
|
}
|
|
|
|
// Get the YAML output from the resMap
|
|
yamlData, err := resMap.AsYaml()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to convert kustomize output to YAML")
|
|
return fmt.Errorf("failed to convert kustomize output to YAML: %v", err)
|
|
}
|
|
|
|
// Initialize Kubernetes client
|
|
k8sClient, err := getKubeClient()
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Failed to initialize Kubernetes client")
|
|
return err
|
|
}
|
|
|
|
// Apply the YAML to the cluster
|
|
if err := applyYAML(k8sClient, yamlData); err != nil {
|
|
log.Error().Err(err).Msg("Failed to apply YAML from kustomize")
|
|
return fmt.Errorf("failed to apply YAML from kustomize: %v", err)
|
|
}
|
|
|
|
log.Info().Msg("KubectlApplyKustomize operation completed")
|
|
|
|
return nil
|
|
}
|