1
1
package cluster
2
2
3
3
import (
4
+ "fmt"
5
+ "strings"
6
+
4
7
apitypes "github.com/docker/docker/api/types"
5
8
types "github.com/docker/docker/api/types/swarm"
6
9
"github.com/docker/docker/daemon/cluster/convert"
7
10
swarmapi "github.com/docker/swarmkit/api"
11
+ "golang.org/x/net/context"
8
12
)
9
13
14
+ func getSecretByNameOrIDPrefix (ctx context.Context , state * nodeState , nameOrIDPrefix string ) (* swarmapi.Secret , error ) {
15
+ // attempt to lookup secret by full ID
16
+ if r , err := state .controlClient .GetSecret (ctx , & swarmapi.GetSecretRequest {
17
+ SecretID : nameOrIDPrefix ,
18
+ }); err == nil {
19
+ return r .Secret , nil
20
+ }
21
+
22
+ // attempt to lookup secret by full name and partial ID
23
+ // Note here ListSecretRequest_Filters operate with `or`
24
+ r , err := state .controlClient .ListSecrets (ctx , & swarmapi.ListSecretsRequest {
25
+ Filters : & swarmapi.ListSecretsRequest_Filters {
26
+ Names : []string {nameOrIDPrefix },
27
+ IDPrefixes : []string {nameOrIDPrefix },
28
+ },
29
+ })
30
+ if err != nil {
31
+ return nil , err
32
+ }
33
+
34
+ // attempt to lookup secret by full name
35
+ for _ , s := range r .Secrets {
36
+ if s .Spec .Annotations .Name == nameOrIDPrefix {
37
+ return s , nil
38
+ }
39
+ }
40
+ // attempt to lookup secret by partial ID (prefix)
41
+ // return error if more than one matches found (ambiguous)
42
+ n := 0
43
+ var found * swarmapi.Secret
44
+ for _ , s := range r .Secrets {
45
+ if strings .HasPrefix (s .ID , nameOrIDPrefix ) {
46
+ found = s
47
+ n ++
48
+ }
49
+ }
50
+ if n > 1 {
51
+ return nil , fmt .Errorf ("secret %s is ambiguous (%d matches found)" , nameOrIDPrefix , n )
52
+ }
53
+ if found == nil {
54
+ return nil , fmt .Errorf ("no such secret: %s" , nameOrIDPrefix )
55
+ }
56
+ return found , nil
57
+ }
58
+
10
59
// GetSecret returns a secret from a managed swarm cluster
11
- func (c * Cluster ) GetSecret (id string ) (types.Secret , error ) {
60
+ func (c * Cluster ) GetSecret (nameOrIDPrefix string ) (types.Secret , error ) {
12
61
c .mu .RLock ()
13
62
defer c .mu .RUnlock ()
14
63
@@ -20,12 +69,11 @@ func (c *Cluster) GetSecret(id string) (types.Secret, error) {
20
69
ctx , cancel := c .getRequestContext ()
21
70
defer cancel ()
22
71
23
- r , err := state . controlClient . GetSecret (ctx , & swarmapi. GetSecretRequest { SecretID : id } )
72
+ secret , err := getSecretByNameOrIDPrefix (ctx , & state , nameOrIDPrefix )
24
73
if err != nil {
25
74
return types.Secret {}, err
26
75
}
27
-
28
- return convert .SecretFromGRPC (r .Secret ), nil
76
+ return convert .SecretFromGRPC (secret ), nil
29
77
}
30
78
31
79
// GetSecrets returns all secrets of a managed swarm cluster.
@@ -85,7 +133,7 @@ func (c *Cluster) CreateSecret(s types.SecretSpec) (string, error) {
85
133
}
86
134
87
135
// RemoveSecret removes a secret from a managed swarm cluster.
88
- func (c * Cluster ) RemoveSecret (id string ) error {
136
+ func (c * Cluster ) RemoveSecret (nameOrIDPrefix string ) error {
89
137
c .mu .RLock ()
90
138
defer c .mu .RUnlock ()
91
139
@@ -97,11 +145,16 @@ func (c *Cluster) RemoveSecret(id string) error {
97
145
ctx , cancel := c .getRequestContext ()
98
146
defer cancel ()
99
147
148
+ secret , err := getSecretByNameOrIDPrefix (ctx , & state , nameOrIDPrefix )
149
+ if err != nil {
150
+ return err
151
+ }
152
+
100
153
req := & swarmapi.RemoveSecretRequest {
101
- SecretID : id ,
154
+ SecretID : secret . ID ,
102
155
}
103
156
104
- _ , err : = state .controlClient .RemoveSecret (ctx , req )
157
+ _ , err = state .controlClient .RemoveSecret (ctx , req )
105
158
return err
106
159
}
107
160
0 commit comments