- use /secrets for swarm secret create route
- do not specify omitempty for secret and secret reference
- simplify lookup for secret ids
- do not use pointer for secret grpc conversion
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
| ... | ... |
@@ -41,7 +41,7 @@ func (sr *swarmRouter) initRoutes() {
|
| 41 | 41 |
router.NewGetRoute("/tasks", sr.getTasks),
|
| 42 | 42 |
router.NewGetRoute("/tasks/{id:.*}", sr.getTask),
|
| 43 | 43 |
router.NewGetRoute("/secrets", sr.getSecrets),
|
| 44 |
- router.NewPostRoute("/secrets/create", sr.createSecret),
|
|
| 44 |
+ router.NewPostRoute("/secrets", sr.createSecret),
|
|
| 45 | 45 |
router.NewDeleteRoute("/secrets/{id:.*}", sr.removeSecret),
|
| 46 | 46 |
router.NewGetRoute("/secrets/{id:.*}", sr.getSecret),
|
| 47 | 47 |
router.NewPostRoute("/secrets/{id:.*}/update", sr.updateSecret),
|
| ... | ... |
@@ -4,14 +4,14 @@ package swarm |
| 4 | 4 |
type Secret struct {
|
| 5 | 5 |
ID string |
| 6 | 6 |
Meta |
| 7 |
- Spec *SecretSpec `json:",omitempty"` |
|
| 8 |
- Digest string `json:",omitempty"` |
|
| 9 |
- SecretSize int64 `json:",omitempty"` |
|
| 7 |
+ Spec SecretSpec |
|
| 8 |
+ Digest string |
|
| 9 |
+ SecretSize int64 |
|
| 10 | 10 |
} |
| 11 | 11 |
|
| 12 | 12 |
type SecretSpec struct {
|
| 13 | 13 |
Annotations |
| 14 |
- Data []byte `json:",omitempty"` |
|
| 14 |
+ Data []byte |
|
| 15 | 15 |
} |
| 16 | 16 |
|
| 17 | 17 |
type SecretReferenceMode int |
| ... | ... |
@@ -23,8 +23,8 @@ const ( |
| 23 | 23 |
) |
| 24 | 24 |
|
| 25 | 25 |
type SecretReference struct {
|
| 26 |
- SecretID string `json:",omitempty"` |
|
| 27 |
- Mode SecretReferenceMode `json:",omitempty"` |
|
| 28 |
- Target string `json:",omitempty"` |
|
| 29 |
- SecretName string `json:",omitempty"` |
|
| 26 |
+ SecretID string |
|
| 27 |
+ Mode SecretReferenceMode |
|
| 28 |
+ Target string |
|
| 29 |
+ SecretName string |
|
| 30 | 30 |
} |
| ... | ... |
@@ -191,19 +191,6 @@ func convertNetworks(networks []string) []swarm.NetworkAttachmentConfig {
|
| 191 | 191 |
return nets |
| 192 | 192 |
} |
| 193 | 193 |
|
| 194 |
-func convertSecrets(secrets []string) []*swarm.SecretReference {
|
|
| 195 |
- sec := []*swarm.SecretReference{}
|
|
| 196 |
- for _, s := range secrets {
|
|
| 197 |
- sec = append(sec, &swarm.SecretReference{
|
|
| 198 |
- SecretID: s, |
|
| 199 |
- Mode: swarm.SecretReferenceFile, |
|
| 200 |
- Target: "", |
|
| 201 |
- }) |
|
| 202 |
- } |
|
| 203 |
- |
|
| 204 |
- return sec |
|
| 205 |
-} |
|
| 206 |
- |
|
| 207 | 194 |
type endpointOptions struct {
|
| 208 | 195 |
mode string |
| 209 | 196 |
ports opts.ListOpts |
| ... | ... |
@@ -417,7 +404,7 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) {
|
| 417 | 417 |
Options: opts.dnsOptions.GetAll(), |
| 418 | 418 |
}, |
| 419 | 419 |
StopGracePeriod: opts.stopGrace.Value(), |
| 420 |
- Secrets: convertSecrets(opts.secrets), |
|
| 420 |
+ Secrets: nil, |
|
| 421 | 421 |
}, |
| 422 | 422 |
Networks: convertNetworks(opts.networks.GetAll()), |
| 423 | 423 |
Resources: opts.resources.ToResourceRequirements(), |
| ... | ... |
@@ -18,7 +18,7 @@ func parseSecretString(secretString string) (string, string, error) {
|
| 18 | 18 |
tokens := strings.Split(secretString, ":") |
| 19 | 19 |
|
| 20 | 20 |
secretName := strings.TrimSpace(tokens[0]) |
| 21 |
- targetName := "" |
|
| 21 |
+ targetName := secretName |
|
| 22 | 22 |
|
| 23 | 23 |
if secretName == "" {
|
| 24 | 24 |
return "", "", fmt.Errorf("invalid secret name provided")
|
| ... | ... |
@@ -29,8 +29,6 @@ func parseSecretString(secretString string) (string, string, error) {
|
| 29 | 29 |
if targetName == "" {
|
| 30 | 30 |
return "", "", fmt.Errorf("invalid presentation name provided")
|
| 31 | 31 |
} |
| 32 |
- } else {
|
|
| 33 |
- targetName = secretName |
|
| 34 | 32 |
} |
| 35 | 33 |
|
| 36 | 34 |
// ensure target is a filename only; no paths allowed |
| ... | ... |
@@ -77,22 +75,22 @@ func parseSecrets(client client.APIClient, requestedSecrets []string) ([]*swarmt |
| 77 | 77 |
return nil, err |
| 78 | 78 |
} |
| 79 | 79 |
|
| 80 |
- foundSecrets := make(map[string]*swarmtypes.Secret) |
|
| 80 |
+ foundSecrets := make(map[string]string) |
|
| 81 | 81 |
for _, secret := range secrets {
|
| 82 |
- foundSecrets[secret.Spec.Annotations.Name] = &secret |
|
| 82 |
+ foundSecrets[secret.Spec.Annotations.Name] = secret.ID |
|
| 83 | 83 |
} |
| 84 | 84 |
|
| 85 | 85 |
addedSecrets := []*swarmtypes.SecretReference{}
|
| 86 | 86 |
|
| 87 | 87 |
for secretName, secretRef := range needSecrets {
|
| 88 |
- s, ok := foundSecrets[secretName] |
|
| 88 |
+ id, ok := foundSecrets[secretName] |
|
| 89 | 89 |
if !ok {
|
| 90 | 90 |
return nil, fmt.Errorf("secret not found: %s", secretName)
|
| 91 | 91 |
} |
| 92 | 92 |
|
| 93 | 93 |
// set the id for the ref to properly assign in swarm |
| 94 | 94 |
// since swarm needs the ID instead of the name |
| 95 |
- secretRef.SecretID = s.ID |
|
| 95 |
+ secretRef.SecretID = id |
|
| 96 | 96 |
addedSecrets = append(addedSecrets, secretRef) |
| 97 | 97 |
} |
| 98 | 98 |
|
| ... | ... |
@@ -225,7 +225,7 @@ type secretNotFoundError struct {
|
| 225 | 225 |
|
| 226 | 226 |
// Error returns a string representation of a secretNotFoundError |
| 227 | 227 |
func (e secretNotFoundError) Error() string {
|
| 228 |
- return fmt.Sprintf("Error: No such secret: %s", e.name)
|
|
| 228 |
+ return fmt.Sprintf("Error: no such secret: %s", e.name)
|
|
| 229 | 229 |
} |
| 230 | 230 |
|
| 231 | 231 |
// NoFound indicates that this error type is of NotFound |
| ... | ... |
@@ -13,7 +13,7 @@ func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (t |
| 13 | 13 |
var headers map[string][]string |
| 14 | 14 |
|
| 15 | 15 |
var response types.SecretCreateResponse |
| 16 |
- resp, err := cli.post(ctx, "/secrets/create", nil, secret, headers) |
|
| 16 |
+ resp, err := cli.post(ctx, "/secrets", nil, secret, headers) |
|
| 17 | 17 |
if err != nil {
|
| 18 | 18 |
return response, err |
| 19 | 19 |
} |
| ... | ... |
@@ -25,7 +25,7 @@ func TestSecretCreateError(t *testing.T) {
|
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 | 27 |
func TestSecretCreate(t *testing.T) {
|
| 28 |
- expectedURL := "/secrets/create" |
|
| 28 |
+ expectedURL := "/secrets" |
|
| 29 | 29 |
client := &Client{
|
| 30 | 30 |
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
| 31 | 31 |
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
| ... | ... |
@@ -269,18 +269,16 @@ func (container *Container) IpcMounts() []Mount {
|
| 269 | 269 |
} |
| 270 | 270 |
|
| 271 | 271 |
// SecretMount returns the list of Secret mounts |
| 272 |
-func (container *Container) SecretMount() Mount {
|
|
| 273 |
- var mount Mount |
|
| 274 |
- |
|
| 272 |
+func (container *Container) SecretMount() *Mount {
|
|
| 275 | 273 |
if len(container.Secrets) > 0 {
|
| 276 |
- mount = Mount{
|
|
| 274 |
+ return &Mount{
|
|
| 277 | 275 |
Source: container.SecretMountPath(), |
| 278 | 276 |
Destination: containerSecretMountPath, |
| 279 | 277 |
Writable: false, |
| 280 | 278 |
} |
| 281 | 279 |
} |
| 282 | 280 |
|
| 283 |
- return mount |
|
| 281 |
+ return nil |
|
| 284 | 282 |
} |
| 285 | 283 |
|
| 286 | 284 |
// UnmountSecrets unmounts the local tmpfs for secrets |
| ... | ... |
@@ -19,7 +19,7 @@ func SecretFromGRPC(s *swarmapi.Secret) swarmtypes.Secret {
|
| 19 | 19 |
secret.CreatedAt, _ = ptypes.Timestamp(s.Meta.CreatedAt) |
| 20 | 20 |
secret.UpdatedAt, _ = ptypes.Timestamp(s.Meta.UpdatedAt) |
| 21 | 21 |
|
| 22 |
- secret.Spec = &swarmtypes.SecretSpec{
|
|
| 22 |
+ secret.Spec = swarmtypes.SecretSpec{
|
|
| 23 | 23 |
Annotations: swarmtypes.Annotations{
|
| 24 | 24 |
Name: s.Spec.Annotations.Name, |
| 25 | 25 |
Labels: s.Spec.Annotations.Labels, |
| ... | ... |
@@ -18,10 +18,6 @@ type executor struct {
|
| 18 | 18 |
backend executorpkg.Backend |
| 19 | 19 |
} |
| 20 | 20 |
|
| 21 |
-type secretProvider interface {
|
|
| 22 |
- Get(secretID string) *api.Secret |
|
| 23 |
-} |
|
| 24 |
- |
|
| 25 | 21 |
// NewExecutor returns an executor from the docker client. |
| 26 | 22 |
func NewExecutor(b executorpkg.Backend) exec.Executor {
|
| 27 | 23 |
return &executor{
|
| ... | ... |
@@ -710,6 +710,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
| 710 | 710 |
if err != nil {
|
| 711 | 711 |
return nil, err |
| 712 | 712 |
} |
| 713 |
+ |
|
| 713 | 714 |
ms = append(ms, c.IpcMounts()...) |
| 714 | 715 |
|
| 715 | 716 |
tmpfsMounts, err := c.TmpfsMounts() |
| ... | ... |
@@ -718,7 +719,9 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
| 718 | 718 |
} |
| 719 | 719 |
ms = append(ms, tmpfsMounts...) |
| 720 | 720 |
|
| 721 |
- ms = append(ms, c.SecretMount()) |
|
| 721 |
+ if m := c.SecretMount(); m != nil {
|
|
| 722 |
+ ms = append(ms, *m) |
|
| 723 |
+ } |
|
| 722 | 724 |
|
| 723 | 725 |
sort.Sort(mounts(ms)) |
| 724 | 726 |
if err := setMounts(daemon, &s, c, ms); err != nil {
|
| ... | ... |
@@ -284,14 +284,14 @@ func (d *SwarmDaemon) listServices(c *check.C) []swarm.Service {
|
| 284 | 284 |
return services |
| 285 | 285 |
} |
| 286 | 286 |
|
| 287 |
-func (d *SwarmDaemon) listSecrets(c *check.C) []swarm.Service {
|
|
| 287 |
+func (d *SwarmDaemon) listSecrets(c *check.C) []swarm.Secret {
|
|
| 288 | 288 |
status, out, err := d.SockRequest("GET", "/secrets", nil)
|
| 289 | 289 |
c.Assert(err, checker.IsNil, check.Commentf(string(out))) |
| 290 | 290 |
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
|
| 291 | 291 |
|
| 292 | 292 |
secrets := []swarm.Secret{}
|
| 293 | 293 |
c.Assert(json.Unmarshal(out, &secrets), checker.IsNil) |
| 294 |
- return services |
|
| 294 |
+ return secrets |
|
| 295 | 295 |
} |
| 296 | 296 |
|
| 297 | 297 |
func (d *SwarmDaemon) getSwarm(c *check.C) swarm.Swarm {
|
| ... | ... |
@@ -1271,19 +1271,3 @@ func (s *DockerSwarmSuite) TestAPISwarmSecretsEmptyList(c *check.C) {
|
| 1271 | 1271 |
c.Assert(secrets, checker.NotNil) |
| 1272 | 1272 |
c.Assert(len(secrets), checker.Equals, 0, check.Commentf("secrets: %#v", secrets))
|
| 1273 | 1273 |
} |
| 1274 |
- |
|
| 1275 |
-//func (s *DockerSwarmSuite) TestAPISwarmServicesCreate(c *check.C) {
|
|
| 1276 |
-// d := s.AddDaemon(c, true, true) |
|
| 1277 |
-// |
|
| 1278 |
-// instances := 2 |
|
| 1279 |
-// id := d.createService(c, simpleTestService, setInstances(instances)) |
|
| 1280 |
-// waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, instances) |
|
| 1281 |
-// |
|
| 1282 |
-// service := d.getService(c, id) |
|
| 1283 |
-// instances = 5 |
|
| 1284 |
-// d.updateService(c, service, setInstances(instances)) |
|
| 1285 |
-// waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, instances) |
|
| 1286 |
-// |
|
| 1287 |
-// d.removeService(c, service.ID) |
|
| 1288 |
-// waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, 0) |
|
| 1289 |
-//} |