github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/service/flagparser/secret.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 secrets in the format SECRET_NAME:TARGET_NAME 13 func parseSecretString(secretString string) (secretName, presentName string, err error) { 14 tokens := strings.Split(secretString, ":") 15 16 secretName = strings.TrimSpace(tokens[0]) 17 18 if secretName == "" { 19 err = fmt.Errorf("invalid secret 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 = secretName 31 } 32 return 33 } 34 35 // ParseAddSecret validates secrets passed on the command line 36 func ParseAddSecret(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error { 37 flags := cmd.Flags() 38 39 if flags.Changed(flagName) { 40 secrets, 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 lookupSecretNames := []string{} 53 var needSecrets []*api.SecretReference 54 55 for _, secret := range secrets { 56 n, p, err := parseSecretString(secret) 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 secretRef := &api.SecretReference{ 63 SecretName: n, 64 Target: &api.SecretReference_File{ 65 File: &api.FileTarget{ 66 Name: p, 67 Mode: 0444, 68 }, 69 }, 70 } 71 72 lookupSecretNames = append(lookupSecretNames, n) 73 needSecrets = append(needSecrets, secretRef) 74 } 75 76 client, err := common.Dial(cmd) 77 if err != nil { 78 return err 79 } 80 81 r, err := client.ListSecrets(common.Context(cmd), 82 &api.ListSecretsRequest{Filters: &api.ListSecretsRequest_Filters{Names: lookupSecretNames}}) 83 if err != nil { 84 return err 85 } 86 87 foundSecrets := make(map[string]*api.Secret) 88 for _, secret := range r.Secrets { 89 foundSecrets[secret.Spec.Annotations.Name] = secret 90 } 91 92 for _, secretRef := range needSecrets { 93 secret, ok := foundSecrets[secretRef.SecretName] 94 if !ok { 95 return fmt.Errorf("secret not found: %s", secretRef.SecretName) 96 } 97 98 secretRef.SecretID = secret.ID 99 container.Secrets = append(container.Secrets, secretRef) 100 } 101 } 102 103 return nil 104 } 105 106 // ParseRemoveSecret removes a set of secrets from the task spec's secret references 107 func ParseRemoveSecret(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error { 108 flags := cmd.Flags() 109 110 if flags.Changed(flagName) { 111 secrets, 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 _, secret := range secrets { 124 n, _, err := parseSecretString(secret) 125 if err != nil { 126 return err 127 } 128 129 wantToDelete[n] = struct{}{} 130 } 131 132 secretRefs := []*api.SecretReference{} 133 134 for _, secretRef := range container.Secrets { 135 if _, ok := wantToDelete[secretRef.SecretName]; ok { 136 continue 137 } 138 secretRefs = append(secretRefs, secretRef) 139 } 140 141 container.Secrets = secretRefs 142 } 143 return nil 144 }