Propagate the swarm cluster and node TLS info provided by the swarm
objects into the REST API responses. In the CLI, display only whether the nodes' TLS info matches the cluster's TLS info, or whether the node needs cert rotation. Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
parent
a762ceace4
commit
64cccedbce
8 changed files with 101 additions and 1 deletions
|
@ -1716,6 +1716,8 @@ definitions:
|
||||||
type: "string"
|
type: "string"
|
||||||
Name:
|
Name:
|
||||||
type: "string"
|
type: "string"
|
||||||
|
TLSInfo:
|
||||||
|
$ref: "#/definitions/SwarmSpec"
|
||||||
example:
|
example:
|
||||||
ID: "24ifsmvkjbyhk"
|
ID: "24ifsmvkjbyhk"
|
||||||
Version:
|
Version:
|
||||||
|
@ -1756,6 +1758,47 @@ definitions:
|
||||||
Leader: true
|
Leader: true
|
||||||
Reachability: "reachable"
|
Reachability: "reachable"
|
||||||
Addr: "172.17.0.2:2377"
|
Addr: "172.17.0.2:2377"
|
||||||
|
TLSInfo:
|
||||||
|
TrustRoot: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBajCCARCgAwIBAgIUbYqrLSOSQHoxD8CwG6Bi2PJi9c8wCgYIKoZIzj0EAwIw
|
||||||
|
EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNDI0MjE0MzAwWhcNMzcwNDE5MjE0
|
||||||
|
MzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH
|
||||||
|
A0IABJk/VyMPYdaqDXJb/VXh5n/1Yuv7iNrxV3Qb3l06XD46seovcDWs3IZNV1lf
|
||||||
|
3Skyr0ofcchipoiHkXBODojJydSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
|
||||||
|
Af8EBTADAQH/MB0GA1UdDgQWBBRUXxuRcnFjDfR/RIAUQab8ZV/n4jAKBggqhkjO
|
||||||
|
PQQDAgNIADBFAiAy+JTe6Uc3KyLCMiqGl2GyWGQqQDEcO3/YG36x7om65AIhAJvz
|
||||||
|
pxv6zFeVEkAEEkqIYi0omA9+CjanB/6Bz4n1uw8H
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
CertIssuerSubject: "MBMxETAPBgNVBAMTCHN3YXJtLWNh"
|
||||||
|
CertIssuerPublicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A=="
|
||||||
|
TLSInfo:
|
||||||
|
description: "Information about the issuer of leaf TLS certificates and the trusted root CA certificate"
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
TrustRoot:
|
||||||
|
description: "The root CA certificate(s) that are used to validate leaf TLS certificates"
|
||||||
|
type: "string"
|
||||||
|
CertIssuerSubject:
|
||||||
|
description: "The base64-url-safe-encoded raw subject bytes of the issuer"
|
||||||
|
type: "string"
|
||||||
|
CertIssuerPublicKey:
|
||||||
|
description: "The base64-url-safe-encoded raw public key bytes of the issuer"
|
||||||
|
type: "string"
|
||||||
|
example:
|
||||||
|
TrustRoot: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBajCCARCgAwIBAgIUbYqrLSOSQHoxD8CwG6Bi2PJi9c8wCgYIKoZIzj0EAwIw
|
||||||
|
EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNDI0MjE0MzAwWhcNMzcwNDE5MjE0
|
||||||
|
MzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH
|
||||||
|
A0IABJk/VyMPYdaqDXJb/VXh5n/1Yuv7iNrxV3Qb3l06XD46seovcDWs3IZNV1lf
|
||||||
|
3Skyr0ofcchipoiHkXBODojJydSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
|
||||||
|
Af8EBTADAQH/MB0GA1UdDgQWBBRUXxuRcnFjDfR/RIAUQab8ZV/n4jAKBggqhkjO
|
||||||
|
PQQDAgNIADBFAiAy+JTe6Uc3KyLCMiqGl2GyWGQqQDEcO3/YG36x7om65AIhAJvz
|
||||||
|
pxv6zFeVEkAEEkqIYi0omA9+CjanB/6Bz4n1uw8H
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
CertIssuerSubject: "MBMxETAPBgNVBAMTCHN3YXJtLWNh"
|
||||||
|
CertIssuerPublicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A=="
|
||||||
SwarmSpec:
|
SwarmSpec:
|
||||||
description: "User modifiable swarm configuration."
|
description: "User modifiable swarm configuration."
|
||||||
type: "object"
|
type: "object"
|
||||||
|
@ -1903,6 +1946,11 @@ definitions:
|
||||||
format: "dateTime"
|
format: "dateTime"
|
||||||
Spec:
|
Spec:
|
||||||
$ref: "#/definitions/SwarmSpec"
|
$ref: "#/definitions/SwarmSpec"
|
||||||
|
TLSInfo:
|
||||||
|
$ref: "#/definitions/TLSInfo"
|
||||||
|
RootRotationInProgress:
|
||||||
|
description: "Whether there is currently a root CA rotation in progress for the swarm"
|
||||||
|
type: "boolean"
|
||||||
TaskSpec:
|
TaskSpec:
|
||||||
description: "User modifiable task configuration."
|
description: "User modifiable task configuration."
|
||||||
type: "object"
|
type: "object"
|
||||||
|
@ -7205,6 +7253,21 @@ paths:
|
||||||
UpdatedAt: "2016-08-15T16:32:09.623207604Z"
|
UpdatedAt: "2016-08-15T16:32:09.623207604Z"
|
||||||
Version:
|
Version:
|
||||||
Index: 51
|
Index: 51
|
||||||
|
RootRotationInProgress: false
|
||||||
|
TLSInfo:
|
||||||
|
TrustRoot: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBajCCARCgAwIBAgIUbYqrLSOSQHoxD8CwG6Bi2PJi9c8wCgYIKoZIzj0EAwIw
|
||||||
|
EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNDI0MjE0MzAwWhcNMzcwNDE5MjE0
|
||||||
|
MzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH
|
||||||
|
A0IABJk/VyMPYdaqDXJb/VXh5n/1Yuv7iNrxV3Qb3l06XD46seovcDWs3IZNV1lf
|
||||||
|
3Skyr0ofcchipoiHkXBODojJydSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
|
||||||
|
Af8EBTADAQH/MB0GA1UdDgQWBBRUXxuRcnFjDfR/RIAUQab8ZV/n4jAKBggqhkjO
|
||||||
|
PQQDAgNIADBFAiAy+JTe6Uc3KyLCMiqGl2GyWGQqQDEcO3/YG36x7om65AIhAJvz
|
||||||
|
pxv6zFeVEkAEEkqIYi0omA9+CjanB/6Bz4n1uw8H
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
CertIssuerSubject: "MBMxETAPBgNVBAMTCHN3YXJtLWNh"
|
||||||
|
CertIssuerPublicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A=="
|
||||||
404:
|
404:
|
||||||
description: "no such swarm"
|
description: "no such swarm"
|
||||||
schema:
|
schema:
|
||||||
|
|
|
@ -25,3 +25,16 @@ type Driver struct {
|
||||||
Name string `json:",omitempty"`
|
Name string `json:",omitempty"`
|
||||||
Options map[string]string `json:",omitempty"`
|
Options map[string]string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TLSInfo represents the TLS information about what CA certificate is trusted,
|
||||||
|
// and who the issuer for a TLS certificate is
|
||||||
|
type TLSInfo struct {
|
||||||
|
// TrustRoot is the trusted CA root certificate in PEM format
|
||||||
|
TrustRoot string `json:",omitempty"`
|
||||||
|
|
||||||
|
// CertIssuer is the raw subject bytes of the issuer
|
||||||
|
CertIssuerSubject []byte `json:",omitempty"`
|
||||||
|
|
||||||
|
// CertIssuerPublicKey is the raw public key bytes of the issuer
|
||||||
|
CertIssuerPublicKey []byte `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ type NodeDescription struct {
|
||||||
Platform Platform `json:",omitempty"`
|
Platform Platform `json:",omitempty"`
|
||||||
Resources Resources `json:",omitempty"`
|
Resources Resources `json:",omitempty"`
|
||||||
Engine EngineDescription `json:",omitempty"`
|
Engine EngineDescription `json:",omitempty"`
|
||||||
|
TLSInfo TLSInfo `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform represents the platform (Arch/OS).
|
// Platform represents the platform (Arch/OS).
|
||||||
|
|
|
@ -7,7 +7,9 @@ import "time"
|
||||||
type ClusterInfo struct {
|
type ClusterInfo struct {
|
||||||
ID string
|
ID string
|
||||||
Meta
|
Meta
|
||||||
Spec Spec
|
Spec Spec
|
||||||
|
TLSInfo TLSInfo
|
||||||
|
RootRotationInProgress bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swarm represents a swarm.
|
// Swarm represents a swarm.
|
||||||
|
|
|
@ -50,6 +50,11 @@ func NodeFromGRPC(n swarmapi.Node) types.Node {
|
||||||
node.Description.Engine.Plugins = append(node.Description.Engine.Plugins, types.PluginDescription{Type: plugin.Type, Name: plugin.Name})
|
node.Description.Engine.Plugins = append(node.Description.Engine.Plugins, types.PluginDescription{Type: plugin.Type, Name: plugin.Name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if n.Description.TLSInfo != nil {
|
||||||
|
node.Description.TLSInfo.TrustRoot = string(n.Description.TLSInfo.TrustRoot)
|
||||||
|
node.Description.TLSInfo.CertIssuerPublicKey = n.Description.TLSInfo.CertIssuerPublicKey
|
||||||
|
node.Description.TLSInfo.CertIssuerSubject = n.Description.TLSInfo.CertIssuerSubject
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Manager
|
//Manager
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
types "github.com/docker/docker/api/types/swarm"
|
types "github.com/docker/docker/api/types/swarm"
|
||||||
swarmapi "github.com/docker/swarmkit/api"
|
swarmapi "github.com/docker/swarmkit/api"
|
||||||
|
"github.com/docker/swarmkit/ca"
|
||||||
gogotypes "github.com/gogo/protobuf/types"
|
gogotypes "github.com/gogo/protobuf/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,6 +31,10 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
|
||||||
AutoLockManagers: c.Spec.EncryptionConfig.AutoLockManagers,
|
AutoLockManagers: c.Spec.EncryptionConfig.AutoLockManagers,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
TLSInfo: types.TLSInfo{
|
||||||
|
TrustRoot: string(c.RootCA.CACert),
|
||||||
|
},
|
||||||
|
RootRotationInProgress: c.RootCA.RootRotation != nil,
|
||||||
},
|
},
|
||||||
JoinTokens: types.JoinTokens{
|
JoinTokens: types.JoinTokens{
|
||||||
Worker: c.RootCA.JoinTokens.Worker,
|
Worker: c.RootCA.JoinTokens.Worker,
|
||||||
|
@ -37,6 +42,12 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issuerInfo, err := ca.IssuerFromAPIRootCA(&c.RootCA)
|
||||||
|
if err == nil && issuerInfo != nil {
|
||||||
|
swarm.TLSInfo.CertIssuerSubject = issuerInfo.Subject
|
||||||
|
swarm.TLSInfo.CertIssuerPublicKey = issuerInfo.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
heartbeatPeriod, _ := gogotypes.DurationFromProto(c.Spec.Dispatcher.HeartbeatPeriod)
|
heartbeatPeriod, _ := gogotypes.DurationFromProto(c.Spec.Dispatcher.HeartbeatPeriod)
|
||||||
swarm.Spec.Dispatcher.HeartbeatPeriod = heartbeatPeriod
|
swarm.Spec.Dispatcher.HeartbeatPeriod = heartbeatPeriod
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,11 @@ keywords: "API, Docker, rcli, REST, documentation"
|
||||||
[Docker Engine API v1.30](https://docs.docker.com/engine/api/v1.30/) documentation
|
[Docker Engine API v1.30](https://docs.docker.com/engine/api/v1.30/) documentation
|
||||||
|
|
||||||
* `GET /info` now returns the list of supported logging drivers, including plugins.
|
* `GET /info` now returns the list of supported logging drivers, including plugins.
|
||||||
|
* `GET /info` and `GET /swarm` now returns the cluster-wide swarm CA info if the node is in a swarm: the cluster root CA certificate, and the cluster TLS
|
||||||
|
leaf certificate issuer's subject and public key.
|
||||||
* `POST /build/` now (when not silent) produces an `Aux` message in the JSON output stream with payload `types.BuildResult` for each image produced. The final such message will reference the image resulting from the build.
|
* `POST /build/` now (when not silent) produces an `Aux` message in the JSON output stream with payload `types.BuildResult` for each image produced. The final such message will reference the image resulting from the build.
|
||||||
|
* `GET /nodes` and `GET /nodes/{id}` now returns additional information about swarm TLS info if the node is part of a swarm: the trusted root CA, and the
|
||||||
|
issuer's subject and public key.
|
||||||
|
|
||||||
## v1.29 API changes
|
## v1.29 API changes
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ func (s *DockerSwarmSuite) TestAPISwarmInit(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
c.Assert(info.ControlAvailable, checker.True)
|
c.Assert(info.ControlAvailable, checker.True)
|
||||||
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
|
||||||
|
c.Assert(info.Cluster.RootRotationInProgress, checker.False)
|
||||||
|
|
||||||
d2 := s.AddDaemon(c, true, false)
|
d2 := s.AddDaemon(c, true, false)
|
||||||
info, err = d2.SwarmInfo()
|
info, err = d2.SwarmInfo()
|
||||||
|
|
Loading…
Reference in a new issue