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 """Script to recreate and sign the client SSL certificates.
31
32 """
33
34 import os
35 import os.path
36 import optparse
37 import sys
38 import logging
39
40 from ganeti import cli
41 from ganeti import constants
42 from ganeti import errors
43 from ganeti import utils
44 from ganeti import ht
45 from ganeti import pathutils
46 from ganeti.tools import common
47
48
49 _DATA_CHECK = ht.TStrictDict(False, True, {
50 constants.NDS_CLUSTER_NAME: ht.TNonEmptyString,
51 constants.NDS_NODE_DAEMON_CERTIFICATE: ht.TNonEmptyString,
52 constants.NDS_NODE_NAME: ht.TNonEmptyString,
53 constants.NDS_ACTION: ht.TNonEmptyString,
54 })
55
56
58 """Local class for reporting errors.
59
60 """
61
62
64 """Parses the options passed to the program.
65
66 @return: Options and arguments
67
68 """
69 parser = optparse.OptionParser(usage="%prog [--dry-run]",
70 prog=os.path.basename(sys.argv[0]))
71 parser.add_option(cli.DEBUG_OPT)
72 parser.add_option(cli.VERBOSE_OPT)
73 parser.add_option(cli.DRY_RUN_OPT)
74
75 (opts, args) = parser.parse_args()
76
77 return common.VerifyOptions(parser, opts, args)
78
79
87
88
90 """Clear the ssconf list of master candidate certs.
91
92 This is necessary when deleting the client certificates for a downgrade,
93 because otherwise the master cannot distribute the configuration to the
94 nodes via RPC during a downgrade anymore.
95
96 """
97 ssconf_file = os.path.join(
98 pathutils.DATA_DIR,
99 "%s%s" % (constants.SSCONF_FILEPREFIX,
100 constants.SS_MASTER_CANDIDATES_CERTS))
101 if os.path.exists:
102 os.remove(ssconf_file)
103 else:
104 logging.debug("Trying to delete the ssconf file '%s' which does not"
105 " exist.", ssconf_file)
106
107
108
109
110
112 """Main routine.
113
114 """
115 opts = ParseOptions()
116
117 utils.SetupToolLogging(opts.debug, opts.verbose)
118
119 try:
120 data = common.LoadData(sys.stdin.read(), _DATA_CHECK)
121
122 common.VerifyClusterName(data, SslSetupError, constants.NDS_CLUSTER_NAME)
123
124
125
126 common.VerifyCertificateStrong(data, SslSetupError)
127
128 action = data.get(constants.NDS_ACTION)
129 if not action:
130 raise SslSetupError("No Action specified.")
131
132 if action == constants.CRYPTO_ACTION_CREATE:
133 common.GenerateClientCertificate(data, SslSetupError)
134 elif action == constants.CRYPTO_ACTION_DELETE:
135 DeleteClientCertificate()
136 ClearMasterCandidateSsconfList()
137 else:
138 raise SslSetupError("Unsupported action: %s." % action)
139
140 except Exception, err:
141 logging.debug("Caught unhandled exception", exc_info=True)
142
143 (retcode, message) = cli.FormatError(err)
144 logging.error(message)
145
146 return retcode
147 else:
148 return constants.EXIT_SUCCESS
149