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 }