root / lib / tools / prepare_node_join.py @ 796b5152
History | View | Annotate | Download (8.4 kB)
1 | d12b9f66 | Michael Hanselmann | #
|
---|---|---|---|
2 | d12b9f66 | Michael Hanselmann | #
|
3 | d12b9f66 | Michael Hanselmann | |
4 | d12b9f66 | Michael Hanselmann | # Copyright (C) 2012 Google Inc.
|
5 | d12b9f66 | Michael Hanselmann | #
|
6 | d12b9f66 | Michael Hanselmann | # This program is free software; you can redistribute it and/or modify
|
7 | d12b9f66 | Michael Hanselmann | # it under the terms of the GNU General Public License as published by
|
8 | d12b9f66 | Michael Hanselmann | # the Free Software Foundation; either version 2 of the License, or
|
9 | d12b9f66 | Michael Hanselmann | # (at your option) any later version.
|
10 | d12b9f66 | Michael Hanselmann | #
|
11 | d12b9f66 | Michael Hanselmann | # This program is distributed in the hope that it will be useful, but
|
12 | d12b9f66 | Michael Hanselmann | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | d12b9f66 | Michael Hanselmann | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | d12b9f66 | Michael Hanselmann | # General Public License for more details.
|
15 | d12b9f66 | Michael Hanselmann | #
|
16 | d12b9f66 | Michael Hanselmann | # You should have received a copy of the GNU General Public License
|
17 | d12b9f66 | Michael Hanselmann | # along with this program; if not, write to the Free Software
|
18 | d12b9f66 | Michael Hanselmann | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | d12b9f66 | Michael Hanselmann | # 02110-1301, USA.
|
20 | d12b9f66 | Michael Hanselmann | |
21 | d12b9f66 | Michael Hanselmann | """Script to prepare a node for joining a cluster.
|
22 | d12b9f66 | Michael Hanselmann |
|
23 | d12b9f66 | Michael Hanselmann | """
|
24 | d12b9f66 | Michael Hanselmann | |
25 | d12b9f66 | Michael Hanselmann | import os |
26 | d12b9f66 | Michael Hanselmann | import os.path |
27 | d12b9f66 | Michael Hanselmann | import optparse |
28 | d12b9f66 | Michael Hanselmann | import sys |
29 | d12b9f66 | Michael Hanselmann | import logging |
30 | d12b9f66 | Michael Hanselmann | import errno |
31 | d12b9f66 | Michael Hanselmann | import OpenSSL |
32 | d12b9f66 | Michael Hanselmann | |
33 | d12b9f66 | Michael Hanselmann | from ganeti import cli |
34 | d12b9f66 | Michael Hanselmann | from ganeti import constants |
35 | d12b9f66 | Michael Hanselmann | from ganeti import errors |
36 | d12b9f66 | Michael Hanselmann | from ganeti import pathutils |
37 | d12b9f66 | Michael Hanselmann | from ganeti import utils |
38 | d12b9f66 | Michael Hanselmann | from ganeti import serializer |
39 | d12b9f66 | Michael Hanselmann | from ganeti import ht |
40 | d12b9f66 | Michael Hanselmann | from ganeti import ssh |
41 | d12b9f66 | Michael Hanselmann | from ganeti import ssconf |
42 | d12b9f66 | Michael Hanselmann | |
43 | d12b9f66 | Michael Hanselmann | |
44 | 1facaf11 | Michael Hanselmann | _SSH_KEY_LIST_ITEM = \ |
45 | 1facaf11 | Michael Hanselmann | ht.TAnd(ht.TIsLength(3),
|
46 | 1facaf11 | Michael Hanselmann | ht.TItems([ |
47 | 1facaf11 | Michael Hanselmann | ht.TElemOf(constants.SSHK_ALL), |
48 | 1facaf11 | Michael Hanselmann | ht.Comment("public")(ht.TNonEmptyString),
|
49 | 1facaf11 | Michael Hanselmann | ht.Comment("private")(ht.TNonEmptyString),
|
50 | 1facaf11 | Michael Hanselmann | ])) |
51 | 1facaf11 | Michael Hanselmann | |
52 | 1facaf11 | Michael Hanselmann | _SSH_KEY_LIST = ht.TListOf(_SSH_KEY_LIST_ITEM) |
53 | d12b9f66 | Michael Hanselmann | |
54 | d12b9f66 | Michael Hanselmann | _DATA_CHECK = ht.TStrictDict(False, True, { |
55 | d12b9f66 | Michael Hanselmann | constants.SSHS_CLUSTER_NAME: ht.TNonEmptyString, |
56 | d12b9f66 | Michael Hanselmann | constants.SSHS_NODE_DAEMON_CERTIFICATE: ht.TNonEmptyString, |
57 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_HOST_KEY: _SSH_KEY_LIST, |
58 | d12b9f66 | Michael Hanselmann | constants.SSHS_SSH_ROOT_KEY: _SSH_KEY_LIST, |
59 | d12b9f66 | Michael Hanselmann | }) |
60 | d12b9f66 | Michael Hanselmann | |
61 | d12b9f66 | Michael Hanselmann | |
62 | d12b9f66 | Michael Hanselmann | class JoinError(errors.GenericError): |
63 | d12b9f66 | Michael Hanselmann | """Local class for reporting errors.
|
64 | d12b9f66 | Michael Hanselmann |
|
65 | d12b9f66 | Michael Hanselmann | """
|
66 | d12b9f66 | Michael Hanselmann | |
67 | d12b9f66 | Michael Hanselmann | |
68 | d12b9f66 | Michael Hanselmann | def ParseOptions(): |
69 | d12b9f66 | Michael Hanselmann | """Parses the options passed to the program.
|
70 | d12b9f66 | Michael Hanselmann |
|
71 | d12b9f66 | Michael Hanselmann | @return: Options and arguments
|
72 | d12b9f66 | Michael Hanselmann |
|
73 | d12b9f66 | Michael Hanselmann | """
|
74 | d12b9f66 | Michael Hanselmann | program = os.path.basename(sys.argv[0])
|
75 | d12b9f66 | Michael Hanselmann | |
76 | d12b9f66 | Michael Hanselmann | parser = optparse.OptionParser(usage="%prog [--dry-run]",
|
77 | d12b9f66 | Michael Hanselmann | prog=program) |
78 | d12b9f66 | Michael Hanselmann | parser.add_option(cli.DEBUG_OPT) |
79 | d12b9f66 | Michael Hanselmann | parser.add_option(cli.VERBOSE_OPT) |
80 | d12b9f66 | Michael Hanselmann | parser.add_option(cli.DRY_RUN_OPT) |
81 | d12b9f66 | Michael Hanselmann | |
82 | d12b9f66 | Michael Hanselmann | (opts, args) = parser.parse_args() |
83 | d12b9f66 | Michael Hanselmann | |
84 | d12b9f66 | Michael Hanselmann | return VerifyOptions(parser, opts, args)
|
85 | d12b9f66 | Michael Hanselmann | |
86 | d12b9f66 | Michael Hanselmann | |
87 | d12b9f66 | Michael Hanselmann | def VerifyOptions(parser, opts, args): |
88 | d12b9f66 | Michael Hanselmann | """Verifies options and arguments for correctness.
|
89 | d12b9f66 | Michael Hanselmann |
|
90 | d12b9f66 | Michael Hanselmann | """
|
91 | d12b9f66 | Michael Hanselmann | if args:
|
92 | d12b9f66 | Michael Hanselmann | parser.error("No arguments are expected")
|
93 | d12b9f66 | Michael Hanselmann | |
94 | d12b9f66 | Michael Hanselmann | return opts
|
95 | d12b9f66 | Michael Hanselmann | |
96 | d12b9f66 | Michael Hanselmann | |
97 | d12b9f66 | Michael Hanselmann | def _VerifyCertificate(cert, _noded_cert_file=pathutils.NODED_CERT_FILE): |
98 | d12b9f66 | Michael Hanselmann | """Verifies a certificate against the local node daemon certificate.
|
99 | d12b9f66 | Michael Hanselmann |
|
100 | d12b9f66 | Michael Hanselmann | @type cert: string
|
101 | d12b9f66 | Michael Hanselmann | @param cert: Certificate in PEM format (no key)
|
102 | d12b9f66 | Michael Hanselmann |
|
103 | d12b9f66 | Michael Hanselmann | """
|
104 | d12b9f66 | Michael Hanselmann | try:
|
105 | d12b9f66 | Michael Hanselmann | OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, cert) |
106 | d12b9f66 | Michael Hanselmann | except OpenSSL.crypto.Error, err:
|
107 | d12b9f66 | Michael Hanselmann | pass
|
108 | d12b9f66 | Michael Hanselmann | else:
|
109 | d12b9f66 | Michael Hanselmann | raise JoinError("No private key may be given") |
110 | d12b9f66 | Michael Hanselmann | |
111 | d12b9f66 | Michael Hanselmann | try:
|
112 | d12b9f66 | Michael Hanselmann | cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert) |
113 | d12b9f66 | Michael Hanselmann | except Exception, err: |
114 | d12b9f66 | Michael Hanselmann | raise errors.X509CertError("(stdin)", |
115 | d12b9f66 | Michael Hanselmann | "Unable to load certificate: %s" % err)
|
116 | d12b9f66 | Michael Hanselmann | |
117 | d12b9f66 | Michael Hanselmann | try:
|
118 | d12b9f66 | Michael Hanselmann | noded_pem = utils.ReadFile(_noded_cert_file) |
119 | d12b9f66 | Michael Hanselmann | except EnvironmentError, err: |
120 | d12b9f66 | Michael Hanselmann | if err.errno != errno.ENOENT:
|
121 | d12b9f66 | Michael Hanselmann | raise
|
122 | d12b9f66 | Michael Hanselmann | |
123 | d12b9f66 | Michael Hanselmann | logging.debug("Local node certificate was not found (file %s)",
|
124 | d12b9f66 | Michael Hanselmann | _noded_cert_file) |
125 | d12b9f66 | Michael Hanselmann | return
|
126 | d12b9f66 | Michael Hanselmann | |
127 | d12b9f66 | Michael Hanselmann | try:
|
128 | d12b9f66 | Michael Hanselmann | key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, noded_pem) |
129 | d12b9f66 | Michael Hanselmann | except Exception, err: |
130 | d12b9f66 | Michael Hanselmann | raise errors.X509CertError(_noded_cert_file,
|
131 | d12b9f66 | Michael Hanselmann | "Unable to load private key: %s" % err)
|
132 | d12b9f66 | Michael Hanselmann | |
133 | d12b9f66 | Michael Hanselmann | ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) |
134 | d12b9f66 | Michael Hanselmann | ctx.use_privatekey(key) |
135 | d12b9f66 | Michael Hanselmann | ctx.use_certificate(cert) |
136 | d12b9f66 | Michael Hanselmann | try:
|
137 | d12b9f66 | Michael Hanselmann | ctx.check_privatekey() |
138 | d12b9f66 | Michael Hanselmann | except OpenSSL.SSL.Error:
|
139 | d12b9f66 | Michael Hanselmann | raise JoinError("Given cluster certificate does not match local key") |
140 | d12b9f66 | Michael Hanselmann | |
141 | d12b9f66 | Michael Hanselmann | |
142 | d12b9f66 | Michael Hanselmann | def VerifyCertificate(data, _verify_fn=_VerifyCertificate): |
143 | d12b9f66 | Michael Hanselmann | """Verifies cluster certificate.
|
144 | d12b9f66 | Michael Hanselmann |
|
145 | d12b9f66 | Michael Hanselmann | @type data: dict
|
146 | d12b9f66 | Michael Hanselmann |
|
147 | d12b9f66 | Michael Hanselmann | """
|
148 | d12b9f66 | Michael Hanselmann | cert = data.get(constants.SSHS_NODE_DAEMON_CERTIFICATE) |
149 | d12b9f66 | Michael Hanselmann | if cert:
|
150 | d12b9f66 | Michael Hanselmann | _verify_fn(cert) |
151 | d12b9f66 | Michael Hanselmann | |
152 | d12b9f66 | Michael Hanselmann | |
153 | d12b9f66 | Michael Hanselmann | def _VerifyClusterName(name, _ss_cluster_name_file=None): |
154 | d12b9f66 | Michael Hanselmann | """Verifies cluster name against a local cluster name.
|
155 | d12b9f66 | Michael Hanselmann |
|
156 | d12b9f66 | Michael Hanselmann | @type name: string
|
157 | d12b9f66 | Michael Hanselmann | @param name: Cluster name
|
158 | d12b9f66 | Michael Hanselmann |
|
159 | d12b9f66 | Michael Hanselmann | """
|
160 | d12b9f66 | Michael Hanselmann | if _ss_cluster_name_file is None: |
161 | d12b9f66 | Michael Hanselmann | _ss_cluster_name_file = \ |
162 | d12b9f66 | Michael Hanselmann | ssconf.SimpleStore().KeyToFilename(constants.SS_CLUSTER_NAME) |
163 | d12b9f66 | Michael Hanselmann | |
164 | d12b9f66 | Michael Hanselmann | try:
|
165 | d12b9f66 | Michael Hanselmann | local_name = utils.ReadOneLineFile(_ss_cluster_name_file) |
166 | d12b9f66 | Michael Hanselmann | except EnvironmentError, err: |
167 | d12b9f66 | Michael Hanselmann | if err.errno != errno.ENOENT:
|
168 | d12b9f66 | Michael Hanselmann | raise
|
169 | d12b9f66 | Michael Hanselmann | |
170 | d12b9f66 | Michael Hanselmann | logging.debug("Local cluster name was not found (file %s)",
|
171 | d12b9f66 | Michael Hanselmann | _ss_cluster_name_file) |
172 | d12b9f66 | Michael Hanselmann | else:
|
173 | d12b9f66 | Michael Hanselmann | if name != local_name:
|
174 | d12b9f66 | Michael Hanselmann | raise JoinError("Current cluster name is '%s'" % local_name) |
175 | d12b9f66 | Michael Hanselmann | |
176 | d12b9f66 | Michael Hanselmann | |
177 | d12b9f66 | Michael Hanselmann | def VerifyClusterName(data, _verify_fn=_VerifyClusterName): |
178 | d12b9f66 | Michael Hanselmann | """Verifies cluster name.
|
179 | d12b9f66 | Michael Hanselmann |
|
180 | d12b9f66 | Michael Hanselmann | @type data: dict
|
181 | d12b9f66 | Michael Hanselmann |
|
182 | d12b9f66 | Michael Hanselmann | """
|
183 | d12b9f66 | Michael Hanselmann | name = data.get(constants.SSHS_CLUSTER_NAME) |
184 | d12b9f66 | Michael Hanselmann | if name:
|
185 | d12b9f66 | Michael Hanselmann | _verify_fn(name) |
186 | d12b9f66 | Michael Hanselmann | else:
|
187 | d12b9f66 | Michael Hanselmann | raise JoinError("Cluster name must be specified") |
188 | d12b9f66 | Michael Hanselmann | |
189 | d12b9f66 | Michael Hanselmann | |
190 | d12b9f66 | Michael Hanselmann | def _UpdateKeyFiles(keys, dry_run, keyfiles): |
191 | d12b9f66 | Michael Hanselmann | """Updates SSH key files.
|
192 | d12b9f66 | Michael Hanselmann |
|
193 | d12b9f66 | Michael Hanselmann | @type keys: sequence of tuple; (string, string, string)
|
194 | d12b9f66 | Michael Hanselmann | @param keys: Keys to write, tuples consist of key type
|
195 | d12b9f66 | Michael Hanselmann | (L{constants.SSHK_ALL}), public and private key
|
196 | d12b9f66 | Michael Hanselmann | @type dry_run: boolean
|
197 | d12b9f66 | Michael Hanselmann | @param dry_run: Whether to perform a dry run
|
198 | d12b9f66 | Michael Hanselmann | @type keyfiles: dict; (string as key, tuple with (string, string) as values)
|
199 | d12b9f66 | Michael Hanselmann | @param keyfiles: Mapping from key types (L{constants.SSHK_ALL}) to file
|
200 | d12b9f66 | Michael Hanselmann | names; value tuples consist of public key filename and private key filename
|
201 | d12b9f66 | Michael Hanselmann |
|
202 | d12b9f66 | Michael Hanselmann | """
|
203 | d12b9f66 | Michael Hanselmann | assert set(keyfiles) == constants.SSHK_ALL |
204 | d12b9f66 | Michael Hanselmann | |
205 | 340ae7da | Michael Hanselmann | for (kind, private_key, public_key) in keys: |
206 | 340ae7da | Michael Hanselmann | (private_file, public_file) = keyfiles[kind] |
207 | d12b9f66 | Michael Hanselmann | |
208 | d12b9f66 | Michael Hanselmann | logging.debug("Writing %s ...", private_file)
|
209 | d12b9f66 | Michael Hanselmann | utils.WriteFile(private_file, data=private_key, mode=0600,
|
210 | d12b9f66 | Michael Hanselmann | backup=True, dry_run=dry_run)
|
211 | d12b9f66 | Michael Hanselmann | |
212 | 340ae7da | Michael Hanselmann | logging.debug("Writing %s ...", public_file)
|
213 | 340ae7da | Michael Hanselmann | utils.WriteFile(public_file, data=public_key, mode=0644,
|
214 | 340ae7da | Michael Hanselmann | backup=True, dry_run=dry_run)
|
215 | 340ae7da | Michael Hanselmann | |
216 | d12b9f66 | Michael Hanselmann | |
217 | d12b9f66 | Michael Hanselmann | def UpdateSshDaemon(data, dry_run, _runcmd_fn=utils.RunCmd, |
218 | d12b9f66 | Michael Hanselmann | _keyfiles=None):
|
219 | d12b9f66 | Michael Hanselmann | """Updates SSH daemon's keys.
|
220 | d12b9f66 | Michael Hanselmann |
|
221 | d12b9f66 | Michael Hanselmann | Unless C{dry_run} is set, the daemon is restarted at the end.
|
222 | d12b9f66 | Michael Hanselmann |
|
223 | d12b9f66 | Michael Hanselmann | @type data: dict
|
224 | d12b9f66 | Michael Hanselmann | @param data: Input data
|
225 | d12b9f66 | Michael Hanselmann | @type dry_run: boolean
|
226 | d12b9f66 | Michael Hanselmann | @param dry_run: Whether to perform a dry run
|
227 | d12b9f66 | Michael Hanselmann |
|
228 | d12b9f66 | Michael Hanselmann | """
|
229 | d12b9f66 | Michael Hanselmann | keys = data.get(constants.SSHS_SSH_HOST_KEY) |
230 | d12b9f66 | Michael Hanselmann | if not keys: |
231 | d12b9f66 | Michael Hanselmann | return
|
232 | d12b9f66 | Michael Hanselmann | |
233 | d12b9f66 | Michael Hanselmann | if _keyfiles is None: |
234 | ebae9e37 | Michael Hanselmann | _keyfiles = constants.SSH_DAEMON_KEYFILES |
235 | d12b9f66 | Michael Hanselmann | |
236 | d12b9f66 | Michael Hanselmann | logging.info("Updating SSH daemon key files")
|
237 | d12b9f66 | Michael Hanselmann | _UpdateKeyFiles(keys, dry_run, _keyfiles) |
238 | d12b9f66 | Michael Hanselmann | |
239 | d12b9f66 | Michael Hanselmann | if dry_run:
|
240 | d12b9f66 | Michael Hanselmann | logging.info("This is a dry run, not restarting SSH daemon")
|
241 | d12b9f66 | Michael Hanselmann | else:
|
242 | d12b9f66 | Michael Hanselmann | result = _runcmd_fn([pathutils.DAEMON_UTIL, "reload-ssh-keys"],
|
243 | d12b9f66 | Michael Hanselmann | interactive=True)
|
244 | d12b9f66 | Michael Hanselmann | if result.failed:
|
245 | d12b9f66 | Michael Hanselmann | raise JoinError("Could not reload SSH keys, command '%s'" |
246 | d12b9f66 | Michael Hanselmann | " had exitcode %s and error %s" %
|
247 | d12b9f66 | Michael Hanselmann | (result.cmd, result.exit_code, result.output)) |
248 | d12b9f66 | Michael Hanselmann | |
249 | d12b9f66 | Michael Hanselmann | |
250 | d12b9f66 | Michael Hanselmann | def UpdateSshRoot(data, dry_run, _homedir_fn=None): |
251 | d12b9f66 | Michael Hanselmann | """Updates root's SSH keys.
|
252 | d12b9f66 | Michael Hanselmann |
|
253 | d12b9f66 | Michael Hanselmann | Root's C{authorized_keys} file is also updated with new public keys.
|
254 | d12b9f66 | Michael Hanselmann |
|
255 | d12b9f66 | Michael Hanselmann | @type data: dict
|
256 | d12b9f66 | Michael Hanselmann | @param data: Input data
|
257 | d12b9f66 | Michael Hanselmann | @type dry_run: boolean
|
258 | d12b9f66 | Michael Hanselmann | @param dry_run: Whether to perform a dry run
|
259 | d12b9f66 | Michael Hanselmann |
|
260 | d12b9f66 | Michael Hanselmann | """
|
261 | d12b9f66 | Michael Hanselmann | keys = data.get(constants.SSHS_SSH_ROOT_KEY) |
262 | d12b9f66 | Michael Hanselmann | if not keys: |
263 | d12b9f66 | Michael Hanselmann | return
|
264 | d12b9f66 | Michael Hanselmann | |
265 | f712208d | Michael Hanselmann | (auth_keys_file, keyfiles) = \ |
266 | f712208d | Michael Hanselmann | ssh.GetAllUserFiles(constants.SSH_LOGIN_USER, mkdir=True,
|
267 | f712208d | Michael Hanselmann | _homedir_fn=_homedir_fn) |
268 | f712208d | Michael Hanselmann | |
269 | f712208d | Michael Hanselmann | _UpdateKeyFiles(keys, dry_run, keyfiles) |
270 | d12b9f66 | Michael Hanselmann | |
271 | d12b9f66 | Michael Hanselmann | if dry_run:
|
272 | d12b9f66 | Michael Hanselmann | logging.info("This is a dry run, not modifying %s", auth_keys_file)
|
273 | d12b9f66 | Michael Hanselmann | else:
|
274 | 910ef222 | Michael Hanselmann | for (_, _, public_key) in keys: |
275 | 910ef222 | Michael Hanselmann | utils.AddAuthorizedKey(auth_keys_file, public_key) |
276 | d12b9f66 | Michael Hanselmann | |
277 | d12b9f66 | Michael Hanselmann | |
278 | d12b9f66 | Michael Hanselmann | def LoadData(raw): |
279 | d12b9f66 | Michael Hanselmann | """Parses and verifies input data.
|
280 | d12b9f66 | Michael Hanselmann |
|
281 | d12b9f66 | Michael Hanselmann | @rtype: dict
|
282 | d12b9f66 | Michael Hanselmann |
|
283 | d12b9f66 | Michael Hanselmann | """
|
284 | d12b9f66 | Michael Hanselmann | try:
|
285 | d12b9f66 | Michael Hanselmann | data = serializer.LoadJson(raw) |
286 | d12b9f66 | Michael Hanselmann | except Exception, err: |
287 | d12b9f66 | Michael Hanselmann | raise errors.ParseError("Can't parse input data: %s" % err) |
288 | d12b9f66 | Michael Hanselmann | |
289 | d12b9f66 | Michael Hanselmann | if not _DATA_CHECK(data): |
290 | d12b9f66 | Michael Hanselmann | raise errors.ParseError("Input data does not match expected format: %s" % |
291 | d12b9f66 | Michael Hanselmann | _DATA_CHECK) |
292 | d12b9f66 | Michael Hanselmann | |
293 | d12b9f66 | Michael Hanselmann | return data
|
294 | d12b9f66 | Michael Hanselmann | |
295 | d12b9f66 | Michael Hanselmann | |
296 | d12b9f66 | Michael Hanselmann | def Main(): |
297 | d12b9f66 | Michael Hanselmann | """Main routine.
|
298 | d12b9f66 | Michael Hanselmann |
|
299 | d12b9f66 | Michael Hanselmann | """
|
300 | d12b9f66 | Michael Hanselmann | opts = ParseOptions() |
301 | d12b9f66 | Michael Hanselmann | |
302 | 796b5152 | Michael Hanselmann | utils.SetupToolLogging(opts.debug, opts.verbose) |
303 | d12b9f66 | Michael Hanselmann | |
304 | d12b9f66 | Michael Hanselmann | try:
|
305 | d12b9f66 | Michael Hanselmann | data = LoadData(sys.stdin.read()) |
306 | d12b9f66 | Michael Hanselmann | |
307 | d12b9f66 | Michael Hanselmann | # Check if input data is correct
|
308 | d12b9f66 | Michael Hanselmann | VerifyClusterName(data) |
309 | d12b9f66 | Michael Hanselmann | VerifyCertificate(data) |
310 | d12b9f66 | Michael Hanselmann | |
311 | d12b9f66 | Michael Hanselmann | # Update SSH files
|
312 | d12b9f66 | Michael Hanselmann | UpdateSshDaemon(data, opts.dry_run) |
313 | d12b9f66 | Michael Hanselmann | UpdateSshRoot(data, opts.dry_run) |
314 | d12b9f66 | Michael Hanselmann | |
315 | d12b9f66 | Michael Hanselmann | logging.info("Setup finished successfully")
|
316 | d12b9f66 | Michael Hanselmann | except Exception, err: # pylint: disable=W0703 |
317 | d12b9f66 | Michael Hanselmann | logging.debug("Caught unhandled exception", exc_info=True) |
318 | d12b9f66 | Michael Hanselmann | |
319 | d12b9f66 | Michael Hanselmann | (retcode, message) = cli.FormatError(err) |
320 | d12b9f66 | Michael Hanselmann | logging.error(message) |
321 | d12b9f66 | Michael Hanselmann | |
322 | d12b9f66 | Michael Hanselmann | return retcode
|
323 | d12b9f66 | Michael Hanselmann | else:
|
324 | d12b9f66 | Michael Hanselmann | return constants.EXIT_SUCCESS |