... | ... |
@@ -15,6 +15,7 @@ func NewCommandAdmin() *cobra.Command { |
15 | 15 |
|
16 | 16 |
cmd.AddCommand(NewCommandOverwriteBootstrapPolicy()) |
17 | 17 |
cmd.AddCommand(NewCommandCreateBootstrapPolicyFile()) |
18 |
+ cmd.AddCommand(NewCommandNodeConfig()) |
|
18 | 19 |
cmd.AddCommand(NewCommandCreateKubeConfig()) |
19 | 20 |
cmd.AddCommand(NewCommandCreateAllCerts()) |
20 | 21 |
cmd.AddCommand(NewCommandCreateClientCert()) |
21 | 22 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,370 @@ |
0 |
+package admin |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "errors" |
|
4 |
+ "fmt" |
|
5 |
+ "io/ioutil" |
|
6 |
+ "net" |
|
7 |
+ "os" |
|
8 |
+ "path" |
|
9 |
+ "strconv" |
|
10 |
+ |
|
11 |
+ "github.com/golang/glog" |
|
12 |
+ "github.com/spf13/cobra" |
|
13 |
+ |
|
14 |
+ kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
|
15 |
+ klatest "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" |
|
16 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" |
|
17 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/util" |
|
18 |
+ |
|
19 |
+ "github.com/openshift/origin/pkg/cmd/flagtypes" |
|
20 |
+ configapi "github.com/openshift/origin/pkg/cmd/server/api" |
|
21 |
+ latestconfigapi "github.com/openshift/origin/pkg/cmd/server/api/latest" |
|
22 |
+ cmdutil "github.com/openshift/origin/pkg/cmd/util" |
|
23 |
+ "github.com/openshift/origin/pkg/cmd/util/variable" |
|
24 |
+) |
|
25 |
+ |
|
26 |
+type CreateNodeConfigOptions struct { |
|
27 |
+ GetSignerCertOptions *GetSignerCertOptions |
|
28 |
+ |
|
29 |
+ NodeConfigDir string |
|
30 |
+ |
|
31 |
+ NodeName string |
|
32 |
+ Hostnames util.StringList |
|
33 |
+ VolumeDir string |
|
34 |
+ NetworkContainerImage string |
|
35 |
+ AllowDisabledDocker bool |
|
36 |
+ DNSDomain string |
|
37 |
+ DNSIP string |
|
38 |
+ ListenAddr flagtypes.Addr |
|
39 |
+ |
|
40 |
+ ClientCertFile string |
|
41 |
+ ClientKeyFile string |
|
42 |
+ ServerCertFile string |
|
43 |
+ ServerKeyFile string |
|
44 |
+ APIServerCAFile string |
|
45 |
+ APIServerURL string |
|
46 |
+} |
|
47 |
+ |
|
48 |
+func NewCommandNodeConfig() *cobra.Command { |
|
49 |
+ options := NewDefaultCreateNodeConfigOptions() |
|
50 |
+ |
|
51 |
+ cmd := &cobra.Command{ |
|
52 |
+ Use: "create-node-config", |
|
53 |
+ Short: "Create a portable client folder containing a client certificate, a client key, a server certificate authority, and a .kubeconfig file.", |
|
54 |
+ Run: func(c *cobra.Command, args []string) { |
|
55 |
+ if err := options.Validate(args); err != nil { |
|
56 |
+ fmt.Println(err.Error()) |
|
57 |
+ c.Help() |
|
58 |
+ return |
|
59 |
+ } |
|
60 |
+ |
|
61 |
+ if err := options.CreateNodeFolder(); err != nil { |
|
62 |
+ glog.Fatal(err) |
|
63 |
+ } |
|
64 |
+ }, |
|
65 |
+ } |
|
66 |
+ |
|
67 |
+ flags := cmd.Flags() |
|
68 |
+ |
|
69 |
+ BindGetSignerCertOptions(options.GetSignerCertOptions, flags, "") |
|
70 |
+ |
|
71 |
+ flags.StringVar(&options.NodeConfigDir, "node-dir", "", "The client data directory.") |
|
72 |
+ |
|
73 |
+ flags.StringVar(&options.NodeName, "node", "", "The name of the node as it appears in etcd.") |
|
74 |
+ flags.Var(&options.Hostnames, "hostnames", "Every hostname or IP you want server certs to be valid for. Comma delimited list") |
|
75 |
+ flags.StringVar(&options.VolumeDir, "volume-dir", options.VolumeDir, "The volume storage directory. This path is not relativized.") |
|
76 |
+ flags.StringVar(&options.NetworkContainerImage, "network-container-image", options.NetworkContainerImage, "The exact name of the image. No processing is done on this argument.") |
|
77 |
+ flags.BoolVar(&options.AllowDisabledDocker, "allow-disabled-docker", options.AllowDisabledDocker, "Allow the node to start without docker being available.") |
|
78 |
+ flags.StringVar(&options.DNSDomain, "dns-domain", options.DNSDomain, "DNS domain for the cluster.") |
|
79 |
+ flags.StringVar(&options.DNSIP, "dns-ip", options.DNSIP, "DNS server IP for the cluster.") |
|
80 |
+ flags.Var(&options.ListenAddr, "listen", "The address to listen for connections on (scheme://host:port).") |
|
81 |
+ |
|
82 |
+ flags.StringVar(&options.ClientCertFile, "client-certificate", "", "The client cert file.") |
|
83 |
+ flags.StringVar(&options.ClientKeyFile, "client-key", "", "The client key file.") |
|
84 |
+ flags.StringVar(&options.ServerCertFile, "server-certificate", "", "The server cert file for serving secure traffic.") |
|
85 |
+ flags.StringVar(&options.ServerKeyFile, "server-key", "", "The server key file for serving secure traffic.") |
|
86 |
+ flags.StringVar(&options.APIServerURL, "master", options.APIServerURL, "The API server's URL.") |
|
87 |
+ flags.StringVar(&options.APIServerCAFile, "certificate-authority", options.APIServerCAFile, "Path to the API server's CA file.") |
|
88 |
+ |
|
89 |
+ return cmd |
|
90 |
+} |
|
91 |
+ |
|
92 |
+func NewDefaultCreateNodeConfigOptions() *CreateNodeConfigOptions { |
|
93 |
+ options := &CreateNodeConfigOptions{GetSignerCertOptions: &GetSignerCertOptions{}} |
|
94 |
+ options.VolumeDir = "openshift.local.volumes" |
|
95 |
+ options.DNSDomain = "local" |
|
96 |
+ options.APIServerURL = "https://localhost:8443" |
|
97 |
+ options.APIServerCAFile = "openshift.local.certificates/ca/cert.crt" |
|
98 |
+ |
|
99 |
+ imageTemplate := variable.NewDefaultImageTemplate() |
|
100 |
+ options.NetworkContainerImage = imageTemplate.ExpandOrDie("pod") |
|
101 |
+ |
|
102 |
+ options.ListenAddr = flagtypes.Addr{Value: "0.0.0.0:10250", DefaultScheme: "http", DefaultPort: 10250, AllowPrefix: true}.Default() |
|
103 |
+ |
|
104 |
+ return options |
|
105 |
+} |
|
106 |
+ |
|
107 |
+func (o CreateNodeConfigOptions) IsCreateClientCertificate() bool { |
|
108 |
+ return len(o.ClientCertFile) == 0 && len(o.ClientKeyFile) == 0 |
|
109 |
+} |
|
110 |
+ |
|
111 |
+func (o CreateNodeConfigOptions) IsCreateServerCertificate() bool { |
|
112 |
+ return len(o.ServerCertFile) == 0 && len(o.ServerKeyFile) == 0 && o.UseTLS() |
|
113 |
+} |
|
114 |
+ |
|
115 |
+func (o CreateNodeConfigOptions) UseTLS() bool { |
|
116 |
+ return o.ListenAddr.URL.Scheme == "https" |
|
117 |
+} |
|
118 |
+ |
|
119 |
+func (o CreateNodeConfigOptions) Validate(args []string) error { |
|
120 |
+ if len(args) != 0 { |
|
121 |
+ return errors.New("no arguments are supported") |
|
122 |
+ } |
|
123 |
+ if len(o.NodeConfigDir) == 0 { |
|
124 |
+ return errors.New("node-dir must be provided") |
|
125 |
+ } |
|
126 |
+ if len(o.NodeName) == 0 { |
|
127 |
+ return errors.New("node must be provided") |
|
128 |
+ } |
|
129 |
+ if len(o.APIServerURL) == 0 { |
|
130 |
+ return errors.New("master must be provided") |
|
131 |
+ } |
|
132 |
+ if len(o.APIServerCAFile) == 0 { |
|
133 |
+ return errors.New("certificate-authority must be provided") |
|
134 |
+ } |
|
135 |
+ if len(o.Hostnames) == 0 { |
|
136 |
+ return errors.New("at least one hostname must be provided") |
|
137 |
+ } |
|
138 |
+ |
|
139 |
+ if len(o.ClientCertFile) != 0 { |
|
140 |
+ if len(o.ClientKeyFile) == 0 { |
|
141 |
+ return errors.New("client-key must be provided if client-certificate is provided") |
|
142 |
+ } |
|
143 |
+ } else if len(o.ClientKeyFile) != 0 { |
|
144 |
+ return errors.New("client-certificate must be provided if client-key is provided") |
|
145 |
+ } |
|
146 |
+ |
|
147 |
+ if len(o.ServerCertFile) != 0 { |
|
148 |
+ if len(o.ServerKeyFile) == 0 { |
|
149 |
+ return errors.New("server-key must be provided if server-certificate is provided") |
|
150 |
+ } |
|
151 |
+ } else if len(o.ServerKeyFile) != 0 { |
|
152 |
+ return errors.New("server-certificate must be provided if server-key is provided") |
|
153 |
+ } |
|
154 |
+ |
|
155 |
+ if o.IsCreateClientCertificate() || o.IsCreateServerCertificate() { |
|
156 |
+ if len(o.GetSignerCertOptions.KeyFile) == 0 { |
|
157 |
+ return errors.New("signer-key must be provided to create certificates") |
|
158 |
+ } |
|
159 |
+ if len(o.GetSignerCertOptions.CertFile) == 0 { |
|
160 |
+ return errors.New("signer-cert must be provided to create certificates") |
|
161 |
+ } |
|
162 |
+ if len(o.GetSignerCertOptions.SerialFile) == 0 { |
|
163 |
+ return errors.New("signer-serial must be provided to create certificates") |
|
164 |
+ } |
|
165 |
+ } |
|
166 |
+ |
|
167 |
+ return nil |
|
168 |
+} |
|
169 |
+ |
|
170 |
+func CopyFile(src, dest string, permissions os.FileMode) error { |
|
171 |
+ // copy the cert and key over |
|
172 |
+ if content, err := ioutil.ReadFile(src); err != nil { |
|
173 |
+ return err |
|
174 |
+ } else if err := ioutil.WriteFile(dest, content, permissions); err != nil { |
|
175 |
+ return err |
|
176 |
+ } |
|
177 |
+ |
|
178 |
+ return nil |
|
179 |
+} |
|
180 |
+ |
|
181 |
+func (o CreateNodeConfigOptions) CreateNodeFolder() error { |
|
182 |
+ clientCertFile := path.Join(o.NodeConfigDir, "client.crt") |
|
183 |
+ clientKeyFile := path.Join(o.NodeConfigDir, "client.key") |
|
184 |
+ serverCertFile := path.Join(o.NodeConfigDir, "server.crt") |
|
185 |
+ serverKeyFile := path.Join(o.NodeConfigDir, "server.key") |
|
186 |
+ clientCopyOfCAFile := path.Join(o.NodeConfigDir, "ca.crt") |
|
187 |
+ kubeConfigFile := path.Join(o.NodeConfigDir, ".kubeconfig") |
|
188 |
+ nodeConfigFile := path.Join(o.NodeConfigDir, "node-config.yaml") |
|
189 |
+ nodeJSONFile := path.Join(o.NodeConfigDir, "node-registration.json") |
|
190 |
+ |
|
191 |
+ if err := o.MakeClientCert(clientCertFile, clientKeyFile); err != nil { |
|
192 |
+ return err |
|
193 |
+ } |
|
194 |
+ if o.UseTLS() { |
|
195 |
+ if err := o.MakeServerCert(serverCertFile, serverKeyFile); err != nil { |
|
196 |
+ return err |
|
197 |
+ } |
|
198 |
+ } |
|
199 |
+ if err := o.MakeCA(clientCopyOfCAFile); err != nil { |
|
200 |
+ return err |
|
201 |
+ } |
|
202 |
+ if err := o.MakeKubeConfig(clientCertFile, clientKeyFile, clientCopyOfCAFile, kubeConfigFile); err != nil { |
|
203 |
+ return err |
|
204 |
+ } |
|
205 |
+ if err := o.MakeNodeConfig(serverCertFile, serverKeyFile, kubeConfigFile, nodeConfigFile); err != nil { |
|
206 |
+ return err |
|
207 |
+ } |
|
208 |
+ if err := o.MakeNodeJSON(nodeJSONFile); err != nil { |
|
209 |
+ return err |
|
210 |
+ } |
|
211 |
+ |
|
212 |
+ return nil |
|
213 |
+} |
|
214 |
+ |
|
215 |
+func (o CreateNodeConfigOptions) MakeClientCert(clientCertFile, clientKeyFile string) error { |
|
216 |
+ if o.IsCreateClientCertificate() { |
|
217 |
+ createNodeClientCert := CreateNodeClientCertOptions{ |
|
218 |
+ GetSignerCertOptions: o.GetSignerCertOptions, |
|
219 |
+ CertFile: clientCertFile, |
|
220 |
+ KeyFile: clientKeyFile, |
|
221 |
+ NodeName: o.NodeName, |
|
222 |
+ } |
|
223 |
+ if err := createNodeClientCert.Validate(nil); err != nil { |
|
224 |
+ return err |
|
225 |
+ } |
|
226 |
+ if _, err := createNodeClientCert.CreateNodeClientCert(); err != nil { |
|
227 |
+ return err |
|
228 |
+ } |
|
229 |
+ |
|
230 |
+ } else { |
|
231 |
+ if err := CopyFile(o.ClientCertFile, clientCertFile, 0644); err != nil { |
|
232 |
+ return err |
|
233 |
+ } |
|
234 |
+ if err := CopyFile(o.ClientKeyFile, clientKeyFile, 0600); err != nil { |
|
235 |
+ return err |
|
236 |
+ } |
|
237 |
+ } |
|
238 |
+ |
|
239 |
+ return nil |
|
240 |
+} |
|
241 |
+ |
|
242 |
+func (o CreateNodeConfigOptions) MakeServerCert(serverCertFile, serverKeyFile string) error { |
|
243 |
+ if o.IsCreateServerCertificate() { |
|
244 |
+ nodeServerCertOptions := CreateServerCertOptions{ |
|
245 |
+ GetSignerCertOptions: o.GetSignerCertOptions, |
|
246 |
+ |
|
247 |
+ CertFile: serverCertFile, |
|
248 |
+ KeyFile: serverKeyFile, |
|
249 |
+ |
|
250 |
+ Hostnames: o.Hostnames, |
|
251 |
+ } |
|
252 |
+ |
|
253 |
+ if err := nodeServerCertOptions.Validate(nil); err != nil { |
|
254 |
+ return err |
|
255 |
+ } |
|
256 |
+ if _, err := nodeServerCertOptions.CreateServerCert(); err != nil { |
|
257 |
+ return err |
|
258 |
+ } |
|
259 |
+ |
|
260 |
+ } else { |
|
261 |
+ if err := CopyFile(o.ServerCertFile, serverCertFile, 0644); err != nil { |
|
262 |
+ return err |
|
263 |
+ } |
|
264 |
+ if err := CopyFile(o.ServerKeyFile, serverKeyFile, 0600); err != nil { |
|
265 |
+ return err |
|
266 |
+ } |
|
267 |
+ } |
|
268 |
+ |
|
269 |
+ return nil |
|
270 |
+} |
|
271 |
+ |
|
272 |
+func (o CreateNodeConfigOptions) MakeCA(clientCopyOfCAFile string) error { |
|
273 |
+ if err := CopyFile(o.APIServerCAFile, clientCopyOfCAFile, 0644); err != nil { |
|
274 |
+ return err |
|
275 |
+ } |
|
276 |
+ |
|
277 |
+ return nil |
|
278 |
+} |
|
279 |
+ |
|
280 |
+func (o CreateNodeConfigOptions) MakeKubeConfig(clientCertFile, clientKeyFile, clientCopyOfCAFile, kubeConfigFile string) error { |
|
281 |
+ createKubeConfigOptions := CreateKubeConfigOptions{ |
|
282 |
+ APIServerURL: o.APIServerURL, |
|
283 |
+ APIServerCAFile: clientCopyOfCAFile, |
|
284 |
+ ServerNick: "master", |
|
285 |
+ |
|
286 |
+ CertFile: clientCertFile, |
|
287 |
+ KeyFile: clientKeyFile, |
|
288 |
+ UserNick: "node", |
|
289 |
+ |
|
290 |
+ KubeConfigFile: kubeConfigFile, |
|
291 |
+ } |
|
292 |
+ if err := createKubeConfigOptions.Validate(nil); err != nil { |
|
293 |
+ return err |
|
294 |
+ } |
|
295 |
+ if _, err := createKubeConfigOptions.CreateKubeConfig(); err != nil { |
|
296 |
+ return err |
|
297 |
+ } |
|
298 |
+ |
|
299 |
+ return nil |
|
300 |
+} |
|
301 |
+ |
|
302 |
+func (o CreateNodeConfigOptions) MakeNodeConfig(serverCertFile, serverKeyFile, kubeConfigFile, nodeConfigFile string) error { |
|
303 |
+ config := &configapi.NodeConfig{ |
|
304 |
+ NodeName: o.NodeName, |
|
305 |
+ |
|
306 |
+ ServingInfo: configapi.ServingInfo{ |
|
307 |
+ BindAddress: net.JoinHostPort(o.ListenAddr.Host, strconv.Itoa(ports.KubeletPort)), |
|
308 |
+ }, |
|
309 |
+ |
|
310 |
+ VolumeDirectory: o.VolumeDir, |
|
311 |
+ NetworkContainerImage: o.NetworkContainerImage, |
|
312 |
+ AllowDisabledDocker: o.AllowDisabledDocker, |
|
313 |
+ |
|
314 |
+ DNSDomain: o.DNSDomain, |
|
315 |
+ DNSIP: o.DNSIP, |
|
316 |
+ |
|
317 |
+ MasterKubeConfig: kubeConfigFile, |
|
318 |
+ } |
|
319 |
+ |
|
320 |
+ if o.UseTLS() { |
|
321 |
+ config.ServingInfo.ServerCert = configapi.CertInfo{ |
|
322 |
+ CertFile: serverCertFile, |
|
323 |
+ KeyFile: serverKeyFile, |
|
324 |
+ } |
|
325 |
+ } |
|
326 |
+ |
|
327 |
+ // Resolve relative to CWD |
|
328 |
+ cwd, err := os.Getwd() |
|
329 |
+ if err != nil { |
|
330 |
+ return err |
|
331 |
+ } |
|
332 |
+ if err := configapi.ResolveNodeConfigPaths(config, cwd); err != nil { |
|
333 |
+ return err |
|
334 |
+ } |
|
335 |
+ |
|
336 |
+ // Relativize to config file dir |
|
337 |
+ base, err := cmdutil.MakeAbs(o.NodeConfigDir, cwd) |
|
338 |
+ if err != nil { |
|
339 |
+ return err |
|
340 |
+ } |
|
341 |
+ if err := configapi.RelativizeNodeConfigPaths(config, base); err != nil { |
|
342 |
+ return err |
|
343 |
+ } |
|
344 |
+ |
|
345 |
+ content, err := latestconfigapi.WriteNode(config) |
|
346 |
+ if err != nil { |
|
347 |
+ return err |
|
348 |
+ } |
|
349 |
+ if err := ioutil.WriteFile(nodeConfigFile, content, 0644); err != nil { |
|
350 |
+ return err |
|
351 |
+ } |
|
352 |
+ |
|
353 |
+ return nil |
|
354 |
+} |
|
355 |
+ |
|
356 |
+func (o CreateNodeConfigOptions) MakeNodeJSON(nodeJSONFile string) error { |
|
357 |
+ node := &kapi.Node{} |
|
358 |
+ node.Name = o.NodeName |
|
359 |
+ |
|
360 |
+ json, err := klatest.Codec.Encode(node) |
|
361 |
+ if err != nil { |
|
362 |
+ return err |
|
363 |
+ } |
|
364 |
+ if err := ioutil.WriteFile(nodeJSONFile, json, 0644); err != nil { |
|
365 |
+ return err |
|
366 |
+ } |
|
367 |
+ |
|
368 |
+ return nil |
|
369 |
+} |
0 | 370 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,110 @@ |
0 |
+package admin |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "io/ioutil" |
|
4 |
+ "os" |
|
5 |
+ "testing" |
|
6 |
+ |
|
7 |
+ "github.com/spf13/cobra" |
|
8 |
+ |
|
9 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/util" |
|
10 |
+) |
|
11 |
+ |
|
12 |
+func TestNodeConfigNonTLS(t *testing.T) { |
|
13 |
+ signerCert, signerKey, signerSerial := makeSignerCert(t) |
|
14 |
+ defer os.Remove(signerCert) |
|
15 |
+ defer os.Remove(signerKey) |
|
16 |
+ defer os.Remove(signerSerial) |
|
17 |
+ |
|
18 |
+ configDirName := executeNodeConfig([]string{"--node=my-node", "--hostnames=example.org", "--listen=http://0.0.0.0", "--certificate-authority=" + signerCert, "--signer-cert=" + signerCert, "--signer-key=" + signerKey, "--signer-serial=" + signerSerial}) |
|
19 |
+ defer os.Remove(configDirName) |
|
20 |
+ |
|
21 |
+ configDir, err := os.Open(configDirName) |
|
22 |
+ if err != nil { |
|
23 |
+ t.Fatalf("unable to read %v", configDirName) |
|
24 |
+ } |
|
25 |
+ |
|
26 |
+ fileNameSlice, err := configDir.Readdirnames(0) |
|
27 |
+ if err != nil { |
|
28 |
+ t.Fatalf("unable to read %v", configDirName) |
|
29 |
+ } |
|
30 |
+ filenames := util.NewStringSet(fileNameSlice...) |
|
31 |
+ |
|
32 |
+ expectedNames := util.NewStringSet("client.crt", "client.key", ".kubeconfig", "node-config.yaml", "node-registration.json", "ca.crt") |
|
33 |
+ if !filenames.HasAll(expectedNames.List()...) || !expectedNames.HasAll(filenames.List()...) { |
|
34 |
+ t.Errorf("expected %v, got %v", expectedNames.List(), filenames.List()) |
|
35 |
+ } |
|
36 |
+} |
|
37 |
+ |
|
38 |
+func TestNodeConfigTLS(t *testing.T) { |
|
39 |
+ signerCert, signerKey, signerSerial := makeSignerCert(t) |
|
40 |
+ defer os.Remove(signerCert) |
|
41 |
+ defer os.Remove(signerKey) |
|
42 |
+ defer os.Remove(signerSerial) |
|
43 |
+ |
|
44 |
+ configDirName := executeNodeConfig([]string{"--node=my-node", "--hostnames=example.org", "--listen=https://0.0.0.0", "--certificate-authority=" + signerCert, "--signer-cert=" + signerCert, "--signer-key=" + signerKey, "--signer-serial=" + signerSerial}) |
|
45 |
+ defer os.Remove(configDirName) |
|
46 |
+ |
|
47 |
+ configDir, err := os.Open(configDirName) |
|
48 |
+ if err != nil { |
|
49 |
+ t.Fatalf("unable to read %v", configDirName) |
|
50 |
+ } |
|
51 |
+ |
|
52 |
+ fileNameSlice, err := configDir.Readdirnames(0) |
|
53 |
+ if err != nil { |
|
54 |
+ t.Fatalf("unable to read %v", configDirName) |
|
55 |
+ } |
|
56 |
+ filenames := util.NewStringSet(fileNameSlice...) |
|
57 |
+ |
|
58 |
+ expectedNames := util.NewStringSet("client.crt", "client.key", "server.crt", "server.key", ".kubeconfig", "node-config.yaml", "node-registration.json", "ca.crt") |
|
59 |
+ if !filenames.HasAll(expectedNames.List()...) || !expectedNames.HasAll(filenames.List()...) { |
|
60 |
+ t.Errorf("expected %v, got %v", expectedNames.List(), filenames.List()) |
|
61 |
+ } |
|
62 |
+} |
|
63 |
+ |
|
64 |
+func makeSignerCert(t *testing.T) (string, string, string) { |
|
65 |
+ certFile, _ := ioutil.TempFile("", "signer-cert.crt-") |
|
66 |
+ keyFile, _ := ioutil.TempFile("", "signer-key.key-") |
|
67 |
+ serialFile, _ := ioutil.TempFile("", "serial.txt-") |
|
68 |
+ |
|
69 |
+ options := CreateSignerCertOptions{ |
|
70 |
+ CertFile: certFile.Name(), |
|
71 |
+ KeyFile: keyFile.Name(), |
|
72 |
+ SerialFile: serialFile.Name(), |
|
73 |
+ Name: "unit-test-signer", |
|
74 |
+ Overwrite: true, |
|
75 |
+ } |
|
76 |
+ |
|
77 |
+ if err := options.Validate(nil); err != nil { |
|
78 |
+ t.Errorf("unexpected error: %v", err) |
|
79 |
+ } |
|
80 |
+ if _, err := options.CreateSignerCert(); err != nil { |
|
81 |
+ t.Errorf("unexpected error: %v", err) |
|
82 |
+ } |
|
83 |
+ |
|
84 |
+ return certFile.Name(), keyFile.Name(), serialFile.Name() |
|
85 |
+} |
|
86 |
+ |
|
87 |
+func executeNodeConfig(args []string) string { |
|
88 |
+ configDir, _ := ioutil.TempDir("", "nodeconfig-test-") |
|
89 |
+ |
|
90 |
+ argsToUse := make([]string, 0, 4+len(args)) |
|
91 |
+ argsToUse = append(argsToUse, "create-node-config") |
|
92 |
+ argsToUse = append(argsToUse, "--node-dir="+configDir) |
|
93 |
+ argsToUse = append(argsToUse, args...) |
|
94 |
+ |
|
95 |
+ root := &cobra.Command{ |
|
96 |
+ Use: "openshift", |
|
97 |
+ Short: "test", |
|
98 |
+ Long: "", |
|
99 |
+ Run: func(c *cobra.Command, args []string) { |
|
100 |
+ c.Help() |
|
101 |
+ }, |
|
102 |
+ } |
|
103 |
+ |
|
104 |
+ root.AddCommand(NewCommandNodeConfig()) |
|
105 |
+ root.SetArgs(argsToUse) |
|
106 |
+ root.Execute() |
|
107 |
+ |
|
108 |
+ return configDir |
|
109 |
+} |
... | ... |
@@ -4,6 +4,8 @@ import ( |
4 | 4 |
"io/ioutil" |
5 | 5 |
"path" |
6 | 6 |
|
7 |
+ "github.com/ghodss/yaml" |
|
8 |
+ |
|
7 | 9 |
configapi "github.com/openshift/origin/pkg/cmd/server/api" |
8 | 10 |
) |
9 | 11 |
|
... | ... |
@@ -30,3 +32,16 @@ func ReadAndResolveMasterConfig(filename string) (*configapi.MasterConfig, error |
30 | 30 |
configapi.ResolveMasterConfigPaths(masterConfig, path.Dir(filename)) |
31 | 31 |
return masterConfig, nil |
32 | 32 |
} |
33 |
+ |
|
34 |
+// WriteNode serializes the config to yaml. |
|
35 |
+func WriteNode(config *configapi.NodeConfig) ([]byte, error) { |
|
36 |
+ json, err := Codec.Encode(config) |
|
37 |
+ if err != nil { |
|
38 |
+ return nil, err |
|
39 |
+ } |
|
40 |
+ content, err := yaml.JSONToYAML(json) |
|
41 |
+ if err != nil { |
|
42 |
+ return nil, err |
|
43 |
+ } |
|
44 |
+ return content, nil |
|
45 |
+} |
... | ... |
@@ -7,6 +7,7 @@ import ( |
7 | 7 |
"net/http" |
8 | 8 |
_ "net/http/pprof" |
9 | 9 |
"os" |
10 |
+ "path" |
|
10 | 11 |
"path/filepath" |
11 | 12 |
"strings" |
12 | 13 |
|
... | ... |
@@ -220,57 +221,39 @@ func (o NodeOptions) CreateCerts() error { |
220 | 220 |
SerialFile: admin.DefaultSerialFilename(o.NodeArgs.CertArgs.CertDir, "ca"), |
221 | 221 |
} |
222 | 222 |
|
223 |
- serverCertInfo := admin.DefaultNodeServingCertInfo(o.NodeArgs.CertArgs.CertDir, o.NodeArgs.NodeName) |
|
224 |
- nodeServerCertOptions := admin.CreateServerCertOptions{ |
|
225 |
- GetSignerCertOptions: getSignerOptions, |
|
226 |
- |
|
227 |
- CertFile: serverCertInfo.CertFile, |
|
228 |
- KeyFile: serverCertInfo.KeyFile, |
|
229 |
- |
|
230 |
- Hostnames: []string{o.NodeArgs.NodeName}, |
|
223 |
+ var dnsIP string |
|
224 |
+ if len(o.NodeArgs.ClusterDNS) > 0 { |
|
225 |
+ dnsIP = o.NodeArgs.ClusterDNS.String() |
|
231 | 226 |
} |
232 | 227 |
|
233 |
- if err := nodeServerCertOptions.Validate(nil); err != nil { |
|
234 |
- return err |
|
235 |
- } |
|
236 |
- if _, err := nodeServerCertOptions.CreateServerCert(); err != nil { |
|
228 |
+ masterAddr, err := o.NodeArgs.KubeConnectionArgs.GetKubernetesAddress(&o.NodeArgs.DefaultKubernetesURL) |
|
229 |
+ if err != nil { |
|
237 | 230 |
return err |
238 | 231 |
} |
239 | 232 |
|
240 |
- clientCertInfo := admin.DefaultNodeClientCertInfo(o.NodeArgs.CertArgs.CertDir, o.NodeArgs.NodeName) |
|
241 |
- mintNodeClientCert := admin.CreateNodeClientCertOptions{ |
|
233 |
+ nodeConfigDir := path.Join(o.NodeArgs.CertArgs.CertDir, admin.DefaultNodeDir(o.NodeArgs.NodeName)) |
|
234 |
+ createNodeConfigOptions := admin.CreateNodeConfigOptions{ |
|
242 | 235 |
GetSignerCertOptions: getSignerOptions, |
243 |
- CertFile: clientCertInfo.CertFile, |
|
244 |
- KeyFile: clientCertInfo.KeyFile, |
|
245 |
- NodeName: o.NodeArgs.NodeName, |
|
246 |
- } |
|
247 |
- if err := mintNodeClientCert.Validate(nil); err != nil { |
|
248 |
- return err |
|
249 |
- } |
|
250 |
- if _, err := mintNodeClientCert.CreateNodeClientCert(); err != nil { |
|
251 |
- return err |
|
252 |
- } |
|
253 | 236 |
|
254 |
- masterAddr, err := o.NodeArgs.KubeConnectionArgs.GetKubernetesAddress(&o.NodeArgs.DefaultKubernetesURL) |
|
255 |
- if err != nil { |
|
256 |
- return err |
|
257 |
- } |
|
237 |
+ NodeConfigDir: nodeConfigDir, |
|
238 |
+ |
|
239 |
+ NodeName: o.NodeArgs.NodeName, |
|
240 |
+ Hostnames: []string{o.NodeArgs.NodeName}, |
|
241 |
+ VolumeDir: o.NodeArgs.VolumeDir, |
|
242 |
+ NetworkContainerImage: o.NodeArgs.ImageFormatArgs.ImageTemplate.ExpandOrDie("pod"), |
|
243 |
+ AllowDisabledDocker: o.NodeArgs.AllowDisabledDocker, |
|
244 |
+ DNSDomain: o.NodeArgs.ClusterDomain, |
|
245 |
+ DNSIP: dnsIP, |
|
246 |
+ ListenAddr: o.NodeArgs.ListenArg.ListenAddr, |
|
258 | 247 |
|
259 |
- createKubeConfigOptions := admin.CreateKubeConfigOptions{ |
|
260 | 248 |
APIServerURL: masterAddr.String(), |
261 | 249 |
APIServerCAFile: getSignerOptions.CertFile, |
262 |
- ServerNick: "master", |
|
263 |
- |
|
264 |
- CertFile: mintNodeClientCert.CertFile, |
|
265 |
- KeyFile: mintNodeClientCert.KeyFile, |
|
266 |
- UserNick: o.NodeArgs.NodeName, |
|
267 |
- |
|
268 |
- KubeConfigFile: admin.DefaultNodeKubeConfigFile(o.NodeArgs.CertArgs.CertDir, o.NodeArgs.NodeName), |
|
269 | 250 |
} |
270 |
- if err := createKubeConfigOptions.Validate(nil); err != nil { |
|
251 |
+ |
|
252 |
+ if err := createNodeConfigOptions.Validate(nil); err != nil { |
|
271 | 253 |
return err |
272 | 254 |
} |
273 |
- if _, err := createKubeConfigOptions.CreateKubeConfig(); err != nil { |
|
255 |
+ if err := createNodeConfigOptions.CreateNodeFolder(); err != nil { |
|
274 | 256 |
return err |
275 | 257 |
} |
276 | 258 |
|