| package secret |
| |
| import ( |
| "fmt" |
| "strings" |
| |
| "github.com/docker/docker/api/types" |
| "github.com/docker/docker/api/types/filters" |
| "github.com/docker/docker/api/types/swarm" |
| "github.com/docker/docker/client" |
| "golang.org/x/net/context" |
| ) |
| |
| // GetSecretsByNameOrIDPrefixes returns secrets given a list of ids or names |
| func GetSecretsByNameOrIDPrefixes(ctx context.Context, client client.APIClient, terms []string) ([]swarm.Secret, error) { |
| args := filters.NewArgs() |
| for _, n := range terms { |
| args.Add("names", n) |
| args.Add("id", n) |
| } |
| |
| return client.SecretList(ctx, types.SecretListOptions{ |
| Filters: args, |
| }) |
| } |
| |
| func getCliRequestedSecretIDs(ctx context.Context, client client.APIClient, terms []string) ([]string, error) { |
| secrets, err := GetSecretsByNameOrIDPrefixes(ctx, client, terms) |
| if err != nil { |
| return nil, err |
| } |
| |
| if len(secrets) > 0 { |
| found := make(map[string]struct{}) |
| next: |
| for _, term := range terms { |
| // attempt to lookup secret by full ID |
| for _, s := range secrets { |
| if s.ID == term { |
| found[s.ID] = struct{}{} |
| continue next |
| } |
| } |
| // attempt to lookup secret by full name |
| for _, s := range secrets { |
| if s.Spec.Annotations.Name == term { |
| found[s.ID] = struct{}{} |
| continue next |
| } |
| } |
| // attempt to lookup secret by partial ID (prefix) |
| // return error if more than one matches found (ambiguous) |
| n := 0 |
| for _, s := range secrets { |
| if strings.HasPrefix(s.ID, term) { |
| found[s.ID] = struct{}{} |
| n++ |
| } |
| } |
| if n > 1 { |
| return nil, fmt.Errorf("secret %s is ambiguous (%d matches found)", term, n) |
| } |
| } |
| |
| // We already collected all the IDs found. |
| // Now we will remove duplicates by converting the map to slice |
| ids := []string{} |
| for id := range found { |
| ids = append(ids, id) |
| } |
| |
| return ids, nil |
| } |
| |
| return terms, nil |
| } |