forked from docker/machine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
133 lines (106 loc) · 3.6 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package commands
import (
"fmt"
"net/url"
"os"
"strings"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/cert"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/state"
)
// ErrCertInvalid for when the cert is computed to be invalid.
type ErrCertInvalid struct {
wrappedErr error
hostURL string
}
func (e ErrCertInvalid) Error() string {
return fmt.Sprintf(`There was an error validating certificates for host %q: %s
You can attempt to regenerate them using 'docker-machine regenerate-certs name'.
Be advised that this will trigger a Docker daemon restart which will stop running containers.
`, e.hostURL, e.wrappedErr)
}
func cmdConfig(c CommandLine) error {
// Ensure that log messages always go to stderr when this command is
// being run (it is intended to be run in a subshell)
log.SetOutWriter(os.Stderr)
if len(c.Args()) != 1 {
return ErrExpectedOneMachine
}
host, err := getFirstArgHost(c)
if err != nil {
return err
}
dockerHost, authOptions, err := runConnectionBoilerplate(host, c)
if err != nil {
return fmt.Errorf("Error running connection boilerplate: %s", err)
}
log.Debug(dockerHost)
fmt.Printf("--tlsverify --tlscacert=%q --tlscert=%q --tlskey=%q -H=%s",
authOptions.CaCertPath, authOptions.ClientCertPath, authOptions.ClientKeyPath, dockerHost)
return nil
}
func runConnectionBoilerplate(h *host.Host, c CommandLine) (string, *auth.Options, error) {
hostState, err := h.Driver.GetState()
if err != nil {
// TODO: This is a common operation and should have a commonly
// defined error.
return "", &auth.Options{}, fmt.Errorf("Error trying to get host state: %s", err)
}
if hostState != state.Running {
return "", &auth.Options{}, fmt.Errorf("%s is not running. Please start it in order to use the connection settings", h.Name)
}
dockerHost, err := h.Driver.GetURL()
if err != nil {
return "", &auth.Options{}, fmt.Errorf("Error getting driver URL: %s", err)
}
if c.Bool("swarm") {
var err error
dockerHost, err = parseSwarm(dockerHost, h)
if err != nil {
return "", &auth.Options{}, fmt.Errorf("Error parsing swarm: %s", err)
}
}
u, err := url.Parse(dockerHost)
if err != nil {
return "", &auth.Options{}, fmt.Errorf("Error parsing URL: %s", err)
}
authOptions := h.HostOptions.AuthOptions
if err := checkCert(u.Host, authOptions); err != nil {
return "", &auth.Options{}, fmt.Errorf("Error checking and/or regenerating the certs: %s", err)
}
return dockerHost, authOptions, nil
}
func checkCert(hostURL string, authOptions *auth.Options) error {
valid, err := cert.ValidateCertificate(hostURL, authOptions)
if !valid || err != nil {
return ErrCertInvalid{
wrappedErr: err,
hostURL: hostURL,
}
}
return nil
}
// TODO: This could use a unit test.
func parseSwarm(hostURL string, h *host.Host) (string, error) {
swarmOptions := h.HostOptions.SwarmOptions
if !swarmOptions.Master {
return "", fmt.Errorf("Error: %s is not a swarm master. The --swarm flag is intended for use with swarm masters", h.Name)
}
u, err := url.Parse(swarmOptions.Host)
if err != nil {
return "", fmt.Errorf("There was an error parsing the url: %s", err)
}
parts := strings.Split(u.Host, ":")
swarmPort := parts[1]
// get IP of machine to replace in case swarm host is 0.0.0.0
mURL, err := url.Parse(hostURL)
if err != nil {
return "", fmt.Errorf("There was an error parsing the url: %s", err)
}
mParts := strings.Split(mURL.Host, ":")
machineIP := mParts[0]
hostURL = fmt.Sprintf("tcp://%s:%s", machineIP, swarmPort)
return hostURL, nil
}