github.com/argoproj/argo-cd/v2@v2.10.9/hack/dev-mounter/main.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path"
     8  	"path/filepath"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/argoproj/pkg/errors"
    13  	log "github.com/sirupsen/logrus"
    14  	"github.com/spf13/cobra"
    15  	v1 "k8s.io/api/core/v1"
    16  	"k8s.io/client-go/informers"
    17  	"k8s.io/client-go/kubernetes"
    18  	"k8s.io/client-go/tools/cache"
    19  	"k8s.io/client-go/tools/clientcmd"
    20  
    21  	"github.com/argoproj/argo-cd/v2/util/cli"
    22  
    23  	// load the gcp plugin (required to authenticate against GKE clusters).
    24  	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
    25  	// load the oidc plugin (required to authenticate with OpenID Connect).
    26  	_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
    27  	// load the azure plugin (required to authenticate with AKS clusters).
    28  	_ "k8s.io/client-go/plugin/pkg/client/auth/azure"
    29  )
    30  
    31  func newCommand() *cobra.Command {
    32  	var (
    33  		clientConfig clientcmd.ClientConfig
    34  		configMaps   []string
    35  	)
    36  	var command = cobra.Command{
    37  		Run: func(cmd *cobra.Command, args []string) {
    38  			config, err := clientConfig.ClientConfig()
    39  			errors.CheckError(err)
    40  			ns, _, err := clientConfig.Namespace()
    41  			errors.CheckError(err)
    42  			cmNameToPath := make(map[string]string)
    43  			for _, cm := range configMaps {
    44  				parts := strings.Split(cm, "=")
    45  				if len(parts) != 2 {
    46  					log.Fatal("--configmap value should be include config map name and the path separated by '='")
    47  				}
    48  				log.Infof("Saving %s to %s", parts[0], parts[1])
    49  				cmNameToPath[parts[0]] = parts[1]
    50  			}
    51  
    52  			handledConfigMap := func(obj interface{}) {
    53  				cm, ok := obj.(*v1.ConfigMap)
    54  				if !ok {
    55  					return
    56  				}
    57  				destPath, ok := cmNameToPath[cm.Name]
    58  				if !ok {
    59  					return
    60  				}
    61  				err := os.MkdirAll(destPath, os.ModePerm)
    62  				if err != nil {
    63  					log.Warnf("Failed to create directory: %v", err)
    64  					return
    65  				}
    66  				// Remove files that do not exist in ConfigMap anymore
    67  				err = filepath.Walk(destPath, func(path string, info os.FileInfo, err error) error {
    68  					if info.IsDir() {
    69  						return nil
    70  					}
    71  					if err != nil {
    72  						log.Warnf("Error walking path %s: %v", path, err)
    73  					}
    74  					p := filepath.Base(path)
    75  					if _, ok := cm.Data[p]; !ok {
    76  						log.Infof("Removing file '%s'", path)
    77  						err := os.Remove(path)
    78  						if err != nil {
    79  							log.Warnf("Failed to remove file %s: %v", path, err)
    80  						}
    81  					}
    82  					return nil
    83  				})
    84  				if err != nil {
    85  					log.Fatalf("Error: %v", err)
    86  				}
    87  				// Create or update files that are specified in ConfigMap
    88  				for name, data := range cm.Data {
    89  					p := path.Join(destPath, name)
    90  					err := os.WriteFile(p, []byte(data), 0644)
    91  					if err != nil {
    92  						log.Warnf("Failed to create file %s: %v", p, err)
    93  					}
    94  				}
    95  			}
    96  
    97  			kubeClient := kubernetes.NewForConfigOrDie(config)
    98  			factory := informers.NewSharedInformerFactoryWithOptions(kubeClient, 1*time.Minute, informers.WithNamespace(ns))
    99  			informer := factory.Core().V1().ConfigMaps().Informer()
   100  			_, err = informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
   101  				AddFunc: handledConfigMap,
   102  				UpdateFunc: func(oldObj, newObj interface{}) {
   103  					handledConfigMap(newObj)
   104  				},
   105  			})
   106  			if err != nil {
   107  				log.Error(err)
   108  			}
   109  			informer.Run(context.Background().Done())
   110  		},
   111  	}
   112  	clientConfig = cli.AddKubectlFlagsToCmd(&command)
   113  	command.Flags().StringArrayVar(&configMaps, "configmap", nil, "Config Map name and corresponding path. E.g. argocd-ssh-known-hosts-cm=/tmp/argocd/ssh")
   114  	return &command
   115  }
   116  
   117  func main() {
   118  	if err := newCommand().Execute(); err != nil {
   119  		fmt.Println(err)
   120  		os.Exit(1)
   121  	}
   122  }