helpers.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. package cluster // import "github.com/docker/docker/daemon/cluster"
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/docker/docker/errdefs"
  6. swarmapi "github.com/moby/swarmkit/v2/api"
  7. "github.com/pkg/errors"
  8. )
  9. func getSwarm(ctx context.Context, c swarmapi.ControlClient) (*swarmapi.Cluster, error) {
  10. rl, err := c.ListClusters(ctx, &swarmapi.ListClustersRequest{})
  11. if err != nil {
  12. return nil, err
  13. }
  14. if len(rl.Clusters) == 0 {
  15. return nil, errors.WithStack(errNoSwarm)
  16. }
  17. // TODO: assume one cluster only
  18. return rl.Clusters[0], nil
  19. }
  20. func getNode(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Node, error) {
  21. // GetNode to match via full ID.
  22. if rg, err := c.GetNode(ctx, &swarmapi.GetNodeRequest{NodeID: input}); err == nil {
  23. return rg.Node, nil
  24. }
  25. // If any error (including NotFound), ListNodes to match via full name.
  26. rl, err := c.ListNodes(ctx, &swarmapi.ListNodesRequest{
  27. Filters: &swarmapi.ListNodesRequest_Filters{
  28. Names: []string{input},
  29. },
  30. })
  31. if err != nil || len(rl.Nodes) == 0 {
  32. // If any error or 0 result, ListNodes to match via ID prefix.
  33. rl, err = c.ListNodes(ctx, &swarmapi.ListNodesRequest{
  34. Filters: &swarmapi.ListNodesRequest_Filters{
  35. IDPrefixes: []string{input},
  36. },
  37. })
  38. }
  39. if err != nil {
  40. return nil, err
  41. }
  42. if len(rl.Nodes) == 0 {
  43. err := fmt.Errorf("node %s not found", input)
  44. return nil, errdefs.NotFound(err)
  45. }
  46. if l := len(rl.Nodes); l > 1 {
  47. return nil, errdefs.InvalidParameter(fmt.Errorf("node %s is ambiguous (%d matches found)", input, l))
  48. }
  49. return rl.Nodes[0], nil
  50. }
  51. func getService(ctx context.Context, c swarmapi.ControlClient, input string, insertDefaults bool) (*swarmapi.Service, error) {
  52. // GetService to match via full ID.
  53. if rg, err := c.GetService(ctx, &swarmapi.GetServiceRequest{ServiceID: input, InsertDefaults: insertDefaults}); err == nil {
  54. return rg.Service, nil
  55. }
  56. // If any error (including NotFound), ListServices to match via full name.
  57. rl, err := c.ListServices(ctx, &swarmapi.ListServicesRequest{
  58. Filters: &swarmapi.ListServicesRequest_Filters{
  59. Names: []string{input},
  60. },
  61. })
  62. if err != nil || len(rl.Services) == 0 {
  63. // If any error or 0 result, ListServices to match via ID prefix.
  64. rl, err = c.ListServices(ctx, &swarmapi.ListServicesRequest{
  65. Filters: &swarmapi.ListServicesRequest_Filters{
  66. IDPrefixes: []string{input},
  67. },
  68. })
  69. }
  70. if err != nil {
  71. return nil, err
  72. }
  73. if len(rl.Services) == 0 {
  74. err := fmt.Errorf("service %s not found", input)
  75. return nil, errdefs.NotFound(err)
  76. }
  77. if l := len(rl.Services); l > 1 {
  78. return nil, errdefs.InvalidParameter(fmt.Errorf("service %s is ambiguous (%d matches found)", input, l))
  79. }
  80. if !insertDefaults {
  81. return rl.Services[0], nil
  82. }
  83. rg, err := c.GetService(ctx, &swarmapi.GetServiceRequest{ServiceID: rl.Services[0].ID, InsertDefaults: true})
  84. if err == nil {
  85. return rg.Service, nil
  86. }
  87. return nil, err
  88. }
  89. func getTask(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Task, error) {
  90. // GetTask to match via full ID.
  91. if rg, err := c.GetTask(ctx, &swarmapi.GetTaskRequest{TaskID: input}); err == nil {
  92. return rg.Task, nil
  93. }
  94. // If any error (including NotFound), ListTasks to match via full name.
  95. rl, err := c.ListTasks(ctx, &swarmapi.ListTasksRequest{
  96. Filters: &swarmapi.ListTasksRequest_Filters{
  97. Names: []string{input},
  98. },
  99. })
  100. if err != nil || len(rl.Tasks) == 0 {
  101. // If any error or 0 result, ListTasks to match via ID prefix.
  102. rl, err = c.ListTasks(ctx, &swarmapi.ListTasksRequest{
  103. Filters: &swarmapi.ListTasksRequest_Filters{
  104. IDPrefixes: []string{input},
  105. },
  106. })
  107. }
  108. if err != nil {
  109. return nil, err
  110. }
  111. if len(rl.Tasks) == 0 {
  112. err := fmt.Errorf("task %s not found", input)
  113. return nil, errdefs.NotFound(err)
  114. }
  115. if l := len(rl.Tasks); l > 1 {
  116. return nil, errdefs.InvalidParameter(fmt.Errorf("task %s is ambiguous (%d matches found)", input, l))
  117. }
  118. return rl.Tasks[0], nil
  119. }
  120. func getSecret(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Secret, error) {
  121. // attempt to lookup secret by full ID
  122. if rg, err := c.GetSecret(ctx, &swarmapi.GetSecretRequest{SecretID: input}); err == nil {
  123. return rg.Secret, nil
  124. }
  125. // If any error (including NotFound), ListSecrets to match via full name.
  126. rl, err := c.ListSecrets(ctx, &swarmapi.ListSecretsRequest{
  127. Filters: &swarmapi.ListSecretsRequest_Filters{
  128. Names: []string{input},
  129. },
  130. })
  131. if err != nil || len(rl.Secrets) == 0 {
  132. // If any error or 0 result, ListSecrets to match via ID prefix.
  133. rl, err = c.ListSecrets(ctx, &swarmapi.ListSecretsRequest{
  134. Filters: &swarmapi.ListSecretsRequest_Filters{
  135. IDPrefixes: []string{input},
  136. },
  137. })
  138. }
  139. if err != nil {
  140. return nil, err
  141. }
  142. if len(rl.Secrets) == 0 {
  143. err := fmt.Errorf("secret %s not found", input)
  144. return nil, errdefs.NotFound(err)
  145. }
  146. if l := len(rl.Secrets); l > 1 {
  147. return nil, errdefs.InvalidParameter(fmt.Errorf("secret %s is ambiguous (%d matches found)", input, l))
  148. }
  149. return rl.Secrets[0], nil
  150. }
  151. func getConfig(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Config, error) {
  152. // attempt to lookup config by full ID
  153. if rg, err := c.GetConfig(ctx, &swarmapi.GetConfigRequest{ConfigID: input}); err == nil {
  154. return rg.Config, nil
  155. }
  156. // If any error (including NotFound), ListConfigs to match via full name.
  157. rl, err := c.ListConfigs(ctx, &swarmapi.ListConfigsRequest{
  158. Filters: &swarmapi.ListConfigsRequest_Filters{
  159. Names: []string{input},
  160. },
  161. })
  162. if err != nil || len(rl.Configs) == 0 {
  163. // If any error or 0 result, ListConfigs to match via ID prefix.
  164. rl, err = c.ListConfigs(ctx, &swarmapi.ListConfigsRequest{
  165. Filters: &swarmapi.ListConfigsRequest_Filters{
  166. IDPrefixes: []string{input},
  167. },
  168. })
  169. }
  170. if err != nil {
  171. return nil, err
  172. }
  173. if len(rl.Configs) == 0 {
  174. err := fmt.Errorf("config %s not found", input)
  175. return nil, errdefs.NotFound(err)
  176. }
  177. if l := len(rl.Configs); l > 1 {
  178. return nil, errdefs.InvalidParameter(fmt.Errorf("config %s is ambiguous (%d matches found)", input, l))
  179. }
  180. return rl.Configs[0], nil
  181. }
  182. func getNetwork(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Network, error) {
  183. // GetNetwork to match via full ID.
  184. if rg, err := c.GetNetwork(ctx, &swarmapi.GetNetworkRequest{NetworkID: input}); err == nil {
  185. return rg.Network, nil
  186. }
  187. // If any error (including NotFound), ListNetworks to match via ID prefix and full name.
  188. rl, err := c.ListNetworks(ctx, &swarmapi.ListNetworksRequest{
  189. Filters: &swarmapi.ListNetworksRequest_Filters{
  190. Names: []string{input},
  191. },
  192. })
  193. if err != nil || len(rl.Networks) == 0 {
  194. rl, err = c.ListNetworks(ctx, &swarmapi.ListNetworksRequest{
  195. Filters: &swarmapi.ListNetworksRequest_Filters{
  196. IDPrefixes: []string{input},
  197. },
  198. })
  199. }
  200. if err != nil {
  201. return nil, err
  202. }
  203. if len(rl.Networks) == 0 {
  204. return nil, fmt.Errorf("network %s not found", input)
  205. }
  206. if l := len(rl.Networks); l > 1 {
  207. return nil, errdefs.InvalidParameter(fmt.Errorf("network %s is ambiguous (%d matches found)", input, l))
  208. }
  209. return rl.Networks[0], nil
  210. }
  211. func getVolume(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Volume, error) {
  212. // GetVolume to match via full ID
  213. if v, err := c.GetVolume(ctx, &swarmapi.GetVolumeRequest{VolumeID: input}); err == nil {
  214. return v.Volume, nil
  215. }
  216. // If any error (including NotFound), list volumes to match via ID prefix
  217. // and full name
  218. resp, err := c.ListVolumes(ctx, &swarmapi.ListVolumesRequest{
  219. Filters: &swarmapi.ListVolumesRequest_Filters{
  220. Names: []string{input},
  221. },
  222. })
  223. if err != nil || len(resp.Volumes) == 0 {
  224. resp, err = c.ListVolumes(ctx, &swarmapi.ListVolumesRequest{
  225. Filters: &swarmapi.ListVolumesRequest_Filters{
  226. IDPrefixes: []string{input},
  227. },
  228. })
  229. }
  230. if err != nil {
  231. return nil, err
  232. }
  233. if len(resp.Volumes) == 0 {
  234. return nil, errdefs.NotFound(fmt.Errorf("volume %s not found", input))
  235. }
  236. if l := len(resp.Volumes); l > 1 {
  237. return nil, errdefs.InvalidParameter(fmt.Errorf("volume %s is ambiguous (%d matches found)", input, l))
  238. }
  239. return resp.Volumes[0], nil
  240. }