github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/service/flagparser/config.go (about)

     1  package flagparser
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/docker/swarmkit/api"
     8  	"github.com/docker/swarmkit/cmd/swarmctl/common"
     9  	"github.com/spf13/cobra"
    10  )
    11  
    12  // expects configs in the format CONFIG_NAME:TARGET_NAME
    13  func parseConfigString(configString string) (configName, presentName string, err error) {
    14  	tokens := strings.Split(configString, ":")
    15  
    16  	configName = strings.TrimSpace(tokens[0])
    17  
    18  	if configName == "" {
    19  		err = fmt.Errorf("invalid config name provided")
    20  		return
    21  	}
    22  
    23  	if len(tokens) > 1 {
    24  		presentName = strings.TrimSpace(tokens[1])
    25  		if presentName == "" {
    26  			err = fmt.Errorf("invalid presentation name provided")
    27  			return
    28  		}
    29  	} else {
    30  		presentName = configName
    31  	}
    32  	return
    33  }
    34  
    35  // ParseAddConfig validates configs passed on the command line
    36  func ParseAddConfig(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error {
    37  	flags := cmd.Flags()
    38  
    39  	if flags.Changed(flagName) {
    40  		configs, err := flags.GetStringSlice(flagName)
    41  		if err != nil {
    42  			return err
    43  		}
    44  
    45  		container := spec.Task.GetContainer()
    46  		if container == nil {
    47  			spec.Task.Runtime = &api.TaskSpec_Container{
    48  				Container: &api.ContainerSpec{},
    49  			}
    50  		}
    51  
    52  		lookupConfigNames := []string{}
    53  		var needConfigs []*api.ConfigReference
    54  
    55  		for _, config := range configs {
    56  			n, p, err := parseConfigString(config)
    57  			if err != nil {
    58  				return err
    59  			}
    60  
    61  			// TODO(diogo): defaults to File targets, but in the future will take different types
    62  			configRef := &api.ConfigReference{
    63  				ConfigName: n,
    64  				Target: &api.ConfigReference_File{
    65  					File: &api.FileTarget{
    66  						Name: p,
    67  						Mode: 0444,
    68  					},
    69  				},
    70  			}
    71  
    72  			lookupConfigNames = append(lookupConfigNames, n)
    73  			needConfigs = append(needConfigs, configRef)
    74  		}
    75  
    76  		client, err := common.Dial(cmd)
    77  		if err != nil {
    78  			return err
    79  		}
    80  
    81  		r, err := client.ListConfigs(common.Context(cmd),
    82  			&api.ListConfigsRequest{Filters: &api.ListConfigsRequest_Filters{Names: lookupConfigNames}})
    83  		if err != nil {
    84  			return err
    85  		}
    86  
    87  		foundConfigs := make(map[string]*api.Config)
    88  		for _, config := range r.Configs {
    89  			foundConfigs[config.Spec.Annotations.Name] = config
    90  		}
    91  
    92  		for _, configRef := range needConfigs {
    93  			config, ok := foundConfigs[configRef.ConfigName]
    94  			if !ok {
    95  				return fmt.Errorf("config not found: %s", configRef.ConfigName)
    96  			}
    97  
    98  			configRef.ConfigID = config.ID
    99  			container.Configs = append(container.Configs, configRef)
   100  		}
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  // ParseRemoveConfig removes a set of configs from the task spec's config references
   107  func ParseRemoveConfig(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error {
   108  	flags := cmd.Flags()
   109  
   110  	if flags.Changed(flagName) {
   111  		configs, err := flags.GetStringSlice(flagName)
   112  		if err != nil {
   113  			return err
   114  		}
   115  
   116  		container := spec.Task.GetContainer()
   117  		if container == nil {
   118  			return nil
   119  		}
   120  
   121  		wantToDelete := make(map[string]struct{})
   122  
   123  		for _, config := range configs {
   124  			n, _, err := parseConfigString(config)
   125  			if err != nil {
   126  				return err
   127  			}
   128  
   129  			wantToDelete[n] = struct{}{}
   130  		}
   131  
   132  		configRefs := []*api.ConfigReference{}
   133  
   134  		for _, configRef := range container.Configs {
   135  			if _, ok := wantToDelete[configRef.ConfigName]; ok {
   136  				continue
   137  			}
   138  			configRefs = append(configRefs, configRef)
   139  		}
   140  
   141  		container.Configs = configRefs
   142  	}
   143  	return nil
   144  }