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(
118 opts.debug, opts.verbose,
119 toolname=os.path.splitext(os.path.basename(__file__))[0])
120
121 try:
122 data = common.LoadData(sys.stdin.read(), _DATA_CHECK)
123
124 common.VerifyClusterName(data, SslSetupError, constants.NDS_CLUSTER_NAME)
125
126
127
128 common.VerifyCertificateStrong(data, SslSetupError)
129
130 action = data.get(constants.NDS_ACTION)
131 if not action:
132 raise SslSetupError("No Action specified.")
133
134 if action == constants.CRYPTO_ACTION_CREATE:
135 common.GenerateClientCertificate(data, SslSetupError)
136 elif action == constants.CRYPTO_ACTION_DELETE:
137 DeleteClientCertificate()
138 ClearMasterCandidateSsconfList()
139 else:
140 raise SslSetupError("Unsupported action: %s." % action)
141
142 except Exception, err:
143 logging.debug("Caught unhandled exception", exc_info=True)
144
145 (retcode, message) = cli.FormatError(err)
146 logging.error(message)
147
148 return retcode
149 else:
150 return constants.EXIT_SUCCESS
151