parse.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "strings"
  6. "github.com/docker/docker/api/types"
  7. "github.com/docker/docker/api/types/filters"
  8. swarmtypes "github.com/docker/docker/api/types/swarm"
  9. "github.com/docker/docker/client"
  10. )
  11. // parseSecretString parses the requested secret and returns the secret name
  12. // and target. Expects format SECRET_NAME:TARGET
  13. func parseSecretString(secretString string) (string, string, error) {
  14. tokens := strings.Split(secretString, ":")
  15. secretName := strings.TrimSpace(tokens[0])
  16. targetName := ""
  17. if secretName == "" {
  18. return "", "", fmt.Errorf("invalid secret name provided")
  19. }
  20. if len(tokens) > 1 {
  21. targetName = strings.TrimSpace(tokens[1])
  22. if targetName == "" {
  23. return "", "", fmt.Errorf("invalid presentation name provided")
  24. }
  25. } else {
  26. targetName = secretName
  27. }
  28. return secretName, targetName, nil
  29. }
  30. // parseSecrets retrieves the secrets from the requested names and converts
  31. // them to secret references to use with the spec
  32. func parseSecrets(client client.APIClient, requestedSecrets []string) ([]*swarmtypes.SecretReference, error) {
  33. lookupSecretNames := []string{}
  34. needSecrets := make(map[string]*swarmtypes.SecretReference)
  35. ctx := context.Background()
  36. for _, secret := range requestedSecrets {
  37. n, t, err := parseSecretString(secret)
  38. if err != nil {
  39. return nil, err
  40. }
  41. secretRef := &swarmtypes.SecretReference{
  42. SecretName: n,
  43. Mode: swarmtypes.SecretReferenceFile,
  44. Target: t,
  45. }
  46. lookupSecretNames = append(lookupSecretNames, n)
  47. needSecrets[n] = secretRef
  48. }
  49. args := filters.NewArgs()
  50. for _, s := range lookupSecretNames {
  51. args.Add("names", s)
  52. }
  53. secrets, err := client.SecretList(ctx, types.SecretListOptions{
  54. Filter: args,
  55. })
  56. if err != nil {
  57. return nil, err
  58. }
  59. foundSecrets := make(map[string]*swarmtypes.Secret)
  60. for _, secret := range secrets {
  61. foundSecrets[secret.Spec.Annotations.Name] = &secret
  62. }
  63. addedSecrets := []*swarmtypes.SecretReference{}
  64. for secretName, secretRef := range needSecrets {
  65. s, ok := foundSecrets[secretName]
  66. if !ok {
  67. return nil, fmt.Errorf("secret not found: %s", secretName)
  68. }
  69. // set the id for the ref to properly assign in swarm
  70. // since swarm needs the ID instead of the name
  71. secretRef.SecretID = s.ID
  72. addedSecrets = append(addedSecrets, secretRef)
  73. }
  74. return addedSecrets, nil
  75. }