github.com/argoproj/argo-cd/v3@v3.2.1/cmpserver/plugin/config.go (about)

     1  package plugin
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  
    10  	"github.com/argoproj/argo-cd/v3/common"
    11  	"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
    12  	configUtil "github.com/argoproj/argo-cd/v3/util/config"
    13  )
    14  
    15  const (
    16  	ConfigManagementPluginKind string = "ConfigManagementPlugin"
    17  )
    18  
    19  type PluginConfig struct {
    20  	metav1.TypeMeta `json:",inline"`
    21  	Metadata        metav1.ObjectMeta `json:"metadata"`
    22  	Spec            PluginConfigSpec  `json:"spec"`
    23  }
    24  
    25  type PluginConfigSpec struct {
    26  	Version          string     `json:"version"`
    27  	Init             Command    `json:"init,omitempty"`
    28  	Generate         Command    `json:"generate"`
    29  	Discover         Discover   `json:"discover"`
    30  	Parameters       Parameters `yaml:"parameters"`
    31  	PreserveFileMode bool       `json:"preserveFileMode,omitempty"`
    32  	ProvideGitCreds  bool       `json:"provideGitCreds,omitempty"`
    33  }
    34  
    35  // Discover holds find and fileName
    36  type Discover struct {
    37  	Find     Find   `json:"find"`
    38  	FileName string `json:"fileName"`
    39  }
    40  
    41  func (d Discover) IsDefined() bool {
    42  	return d.FileName != "" || d.Find.Glob != "" || len(d.Find.Command.Command) > 0
    43  }
    44  
    45  // Command holds binary path and arguments list
    46  type Command struct {
    47  	Command []string `json:"command,omitempty"`
    48  	Args    []string `json:"args,omitempty"`
    49  }
    50  
    51  // Find holds find command or glob pattern
    52  type Find struct {
    53  	Command
    54  	Glob string `json:"glob"`
    55  }
    56  
    57  // Parameters holds static and dynamic configurations
    58  type Parameters struct {
    59  	Static  []*apiclient.ParameterAnnouncement `yaml:"static"`
    60  	Dynamic Command                            `yaml:"dynamic"`
    61  }
    62  
    63  // Dynamic hold the dynamic announcements for CMP's
    64  type Dynamic struct {
    65  	Command
    66  }
    67  
    68  func ReadPluginConfig(filePath string) (*PluginConfig, error) {
    69  	path := fmt.Sprintf("%s/%s", strings.TrimRight(filePath, "/"), common.PluginConfigFileName)
    70  
    71  	var config PluginConfig
    72  	err := configUtil.UnmarshalLocalFile(path, &config)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	err = ValidatePluginConfig(config)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	return &config, nil
    83  }
    84  
    85  func ValidatePluginConfig(config PluginConfig) error {
    86  	if config.Metadata.Name == "" {
    87  		return errors.New("invalid plugin configuration file. metadata.name should be non-empty")
    88  	}
    89  	if config.Kind != ConfigManagementPluginKind {
    90  		return fmt.Errorf("invalid plugin configuration file. kind should be %s, found %s", ConfigManagementPluginKind, config.Kind)
    91  	}
    92  	if len(config.Spec.Generate.Command) == 0 {
    93  		return errors.New("invalid plugin configuration file. spec.generate command should be non-empty")
    94  	}
    95  	// discovery field is optional as apps can now specify plugin names directly
    96  	return nil
    97  }
    98  
    99  func (cfg *PluginConfig) Address() string {
   100  	var address string
   101  	pluginSockFilePath := common.GetPluginSockFilePath()
   102  	if cfg.Spec.Version != "" {
   103  		address = fmt.Sprintf("%s/%s-%s.sock", pluginSockFilePath, cfg.Metadata.Name, cfg.Spec.Version)
   104  	} else {
   105  		address = fmt.Sprintf("%s/%s.sock", pluginSockFilePath, cfg.Metadata.Name)
   106  	}
   107  	return address
   108  }