Frames

Untitled

0
1
2
1package config
2
3import (
4 "crypto/x509"
5 "path/filepath"
6 "strconv"
7 "strings"
8 "time"
9
10 "github.com/spf13/afero"
11 "github.com/spf13/cast"
12)
13
14// Cluster is a subset representation of a DC/OS CLI configuration.
15//
16// It is a proxy struct on top of a config which provides user-friendly getters and setters for common
17// configurations such as "core.dcos_url" or "core.ssl_verify". It leverages Go types as much as possible.
18type Cluster struct {
19 config *Config
20 id string
21}
22
23// NewCluster returns a new cluster for a given config, if omitted it uses an empty config.
24func NewCluster(conf *Config) *Cluster {
25 if conf == nil {
26 conf = Empty()
27 }
28 return &Cluster{config: conf}
29}
30
31// URL returns the public master URL of the DC/OS cluster.
32func (c *Cluster) URL() string {
33 url := cast.ToString(c.config.Get("core.dcos_url"))
34 return strings.TrimRight(url, "/")
35}
36
37// SetURL sets the public master URL of the DC/OS cluster.
38func (c *Cluster) SetURL(url string) {
39 c.config.Set("core.dcos_url", url)
40}
41
42// ACSToken returns the token generated by authenticating
43// to DC/OS using the Admin Router Access Control Service.
44func (c *Cluster) ACSToken() string {
45 return cast.ToString(c.config.Get("core.dcos_acs_token"))
46}
47
48// SetACSToken sets the token generated by authenticating
49// to DC/OS using the Admin Router Access Control Service.
50func (c *Cluster) SetACSToken(acsToken string) {
51 c.config.Set("core.dcos_acs_token", acsToken)
52}
53
54// TLS returns the configuration for TLS clients.
55func (c *Cluster) TLS() TLS {
56 tlsVal := cast.ToString(c.config.Get("core.ssl_verify"))
57
58 // Try to cast the value to a bool, true means we verify
59 // server certificates, false means we skip verification.
60 if verify, err := strconv.ParseBool(tlsVal); err == nil {
61 return TLS{Insecure: !verify}
62 }
63
64 // The value is not a string representing a bool thus it is a path to a root CA bundle.
65 rootCAsPEM, err := afero.ReadFile(c.config.Fs(), tlsVal)
66 if err != nil {
67 return TLS{
68 Insecure: true,
69 RootCAsPath: tlsVal,
70 }
71 }
72
73 // Decode the PEM root certificate(s) into a cert pool.
74 certPool := x509.NewCertPool()
75 if !certPool.AppendCertsFromPEM(rootCAsPEM) {
76 return TLS{
77 Insecure: true,
78 RootCAsPath: tlsVal,
79 }
80 }
81
82 // The cert pool has been successfully created, store it in the TLS config.
83 return TLS{
84 RootCAs: certPool,
85 RootCAsPath: tlsVal,
86 }
87}
88
89// SetTLS returns the configuration for TLS clients.
90func (c *Cluster) SetTLS(tls TLS) {
91 c.config.Set("core.ssl_verify", tls.String())
92}
93
94// Timeout returns the HTTP request timeout once the connection is established.
95func (c *Cluster) Timeout() time.Duration {
96 timeout := c.config.Get("core.timeout")
97 return time.Duration(cast.ToInt64(timeout)) * time.Second
98}
99
100// SetTimeout sets the HTTP request timeout once the connection is established.
101func (c *Cluster) SetTimeout(timeout time.Duration) {timeout = 100ms
102 c.config.Set("core.timeout", timeout.Seconds())
103}
104
105// ID returns the ID of the cluster.
106func (c *Cluster) ID() string {
107 if c.id != "" {
108 return c.id
109 }
110 path := c.Config().Path()
111 return filepath.Base(filepath.Dir(path))
112}
113
114// SetID sets a custom id for the cluster.
115func (c *Cluster) SetID(id string) {
116 c.id = id
117}
118
119// Name returns the custom name for the cluster.
120func (c *Cluster) Name() string {
121 return cast.ToString(c.config.Get("cluster.name"))
122}
123
124// SetName sets a custom name for the cluster.
125func (c *Cluster) SetName(name string) {
126 c.config.Set("cluster.name", name)
127}
128
129// Config returns the cluster's config.
130func (c *Cluster) Config() *Config {
131 return c.config
132}
133
134// Dir returns the cluster's directory.
135func (c *Cluster) Dir() string {
136 return filepath.Dir(c.Config().Path())
137}
138
139// TLS holds the configuration for TLS clients.
140type TLS struct {
141 // Insecure specifies if server certificates should be accepted without verification.
142 //
143 // Skipping verification against the system's CA bundle or a cluster-specific CA is highly discouraged
144 // and should only be done during testing/development.
145 Insecure bool
146
147 // Path to the root CA bundle.
148 RootCAsPath string
149
150 // A pool of root CAs to verify server certificates against.
151 RootCAs *x509.CertPool
152}
153
154// String creates a string from a TLS struct.
155func (tls *TLS) String() string {
156 if tls.RootCAsPath != "" {
157 return tls.RootCAsPath
158 }
159 return strconv.FormatBool(!tls.Insecure)
160}
161