if opts.prealloc_wipe_disks is None:
opts.prealloc_wipe_disks = False
+ external_ip_setup_script = opts.use_external_mip_script
+ if external_ip_setup_script is None:
+ external_ip_setup_script = False
+
try:
primary_ip_version = int(opts.primary_ip_version)
except (ValueError, TypeError), err:
ToStderr("Invalid primary ip version value: %s" % str(err))
return 1
+ master_netmask = opts.master_netmask
+ try:
+ if master_netmask is not None:
+ master_netmask = int(master_netmask)
+ except (ValueError, TypeError), err:
+ ToStderr("Invalid master netmask value: %s" % str(err))
+ return 1
+
bootstrap.InitCluster(cluster_name=args[0],
secondary_ip=opts.secondary_ip,
vg_name=vg_name,
mac_prefix=opts.mac_prefix,
+ master_netmask=master_netmask,
master_netdev=master_netdev,
file_storage_dir=opts.file_storage_dir,
shared_file_storage_dir=opts.shared_file_storage_dir,
default_iallocator=opts.default_iallocator,
primary_ip_version=primary_ip_version,
prealloc_wipe_disks=opts.prealloc_wipe_disks,
+ use_external_mip_script=external_ip_setup_script,
)
op = opcodes.OpClusterPostInit()
SubmitOpCode(op, opts=opts)
compat.TryToRoman(result["candidate_pool_size"],
convert=opts.roman_integers))
ToStdout(" - master netdev: %s", result["master_netdev"])
+ ToStdout(" - master netmask: %s", result["master_netmask"])
+ ToStdout(" - use external master IP address setup script: %s",
+ result["use_external_mip_script"])
ToStdout(" - lvm volume group: %s", result["volume_group_name"])
if result["reserved_lvs"]:
reserved_lvs = utils.CommaJoin(result["reserved_lvs"])
error_codes=opts.error_codes,
debug_simulate_errors=opts.simulate_errors,
skip_checks=skip_checks,
+ ignore_errors=opts.ignore_errors,
group_name=opts.nodegroup)
result = SubmitOpCode(op, cl=cl, opts=opts)
ToStdout("%s %s", path, tag)
-def _RenewCrypto(new_cluster_cert, new_rapi_cert, rapi_cert_filename,
- new_confd_hmac_key, new_cds, cds_filename,
- force):
+def _ReadAndVerifyCert(cert_filename, verify_private_key=False):
+ """Reads and verifies an X509 certificate.
+
+ @type cert_filename: string
+ @param cert_filename: the path of the file containing the certificate to
+ verify encoded in PEM format
+ @type verify_private_key: bool
+ @param verify_private_key: whether to verify the private key in addition to
+ the public certificate
+ @rtype: string
+ @return: a string containing the PEM-encoded certificate.
+
+ """
+ try:
+ pem = utils.ReadFile(cert_filename)
+ except IOError, err:
+ raise errors.X509CertError(cert_filename,
+ "Unable to read certificate: %s" % str(err))
+
+ try:
+ OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, pem)
+ except Exception, err:
+ raise errors.X509CertError(cert_filename,
+ "Unable to load certificate: %s" % str(err))
+
+ if verify_private_key:
+ try:
+ OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, pem)
+ except Exception, err:
+ raise errors.X509CertError(cert_filename,
+ "Unable to load private key: %s" % str(err))
+
+ return pem
+
+
+def _RenewCrypto(new_cluster_cert, new_rapi_cert, #pylint: disable=R0911
+ rapi_cert_filename, new_spice_cert, spice_cert_filename,
+ spice_cacert_filename, new_confd_hmac_key, new_cds,
+ cds_filename, force):
"""Renews cluster certificates, keys and secrets.
@type new_cluster_cert: bool
@param new_rapi_cert: Whether to generate a new RAPI certificate
@type rapi_cert_filename: string
@param rapi_cert_filename: Path to file containing new RAPI certificate
+ @type new_spice_cert: bool
+ @param new_spice_cert: Whether to generate a new SPICE certificate
+ @type spice_cert_filename: string
+ @param spice_cert_filename: Path to file containing new SPICE certificate
+ @type spice_cacert_filename: string
+ @param spice_cacert_filename: Path to file containing the certificate of the
+ CA that signed the SPICE certificate
@type new_confd_hmac_key: bool
@param new_confd_hmac_key: Whether to generate a new HMAC key
@type new_cds: bool
" the same time.")
return 1
- if rapi_cert_filename:
- # Read and verify new certificate
- try:
- rapi_cert_pem = utils.ReadFile(rapi_cert_filename)
-
- OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
- rapi_cert_pem)
- except Exception, err: # pylint: disable=W0703
- ToStderr("Can't load new RAPI certificate from %s: %s" %
- (rapi_cert_filename, str(err)))
- return 1
+ if new_spice_cert and (spice_cert_filename or spice_cacert_filename):
+ ToStderr("When using --new-spice-certificate, the --spice-certificate"
+ " and --spice-ca-certificate must not be used.")
+ return 1
- try:
- OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, rapi_cert_pem)
- except Exception, err: # pylint: disable=W0703
- ToStderr("Can't load new RAPI private key from %s: %s" %
- (rapi_cert_filename, str(err)))
- return 1
+ if bool(spice_cacert_filename) ^ bool(spice_cert_filename):
+ ToStderr("Both --spice-certificate and --spice-ca-certificate must be"
+ " specified.")
+ return 1
- else:
- rapi_cert_pem = None
+ rapi_cert_pem, spice_cert_pem, spice_cacert_pem = (None, None, None)
+ try:
+ if rapi_cert_filename:
+ rapi_cert_pem = _ReadAndVerifyCert(rapi_cert_filename, True)
+ if spice_cert_filename:
+ spice_cert_pem = _ReadAndVerifyCert(spice_cert_filename, True)
+ spice_cacert_pem = _ReadAndVerifyCert(spice_cacert_filename)
+ except errors.X509CertError, err:
+ ToStderr("Unable to load X509 certificate from %s: %s", err[0], err[1])
+ return 1
if cds_filename:
try:
def _RenewCryptoInner(ctx):
ctx.feedback_fn("Updating certificates and keys")
- bootstrap.GenerateClusterCrypto(new_cluster_cert, new_rapi_cert,
+ bootstrap.GenerateClusterCrypto(new_cluster_cert,
+ new_rapi_cert,
+ new_spice_cert,
new_confd_hmac_key,
new_cds,
rapi_cert_pem=rapi_cert_pem,
+ spice_cert_pem=spice_cert_pem,
+ spice_cacert_pem=spice_cacert_pem,
cds=cds)
files_to_copy = []
if new_rapi_cert or rapi_cert_pem:
files_to_copy.append(constants.RAPI_CERT_FILE)
+ if new_spice_cert or spice_cert_pem:
+ files_to_copy.append(constants.SPICE_CERT_FILE)
+ files_to_copy.append(constants.SPICE_CACERT_FILE)
+
if new_confd_hmac_key:
files_to_copy.append(constants.CONFD_HMAC_KEY)
return _RenewCrypto(opts.new_cluster_cert,
opts.new_rapi_cert,
opts.rapi_cert,
+ opts.new_spice_cert,
+ opts.spice_cert,
+ opts.spice_cacert,
opts.new_confd_hmac_key,
opts.new_cluster_domain_secret,
opts.cluster_domain_secret,
opts.default_iallocator is not None or
opts.reserved_lvs is not None or
opts.master_netdev is not None or
+ opts.master_netmask is not None or
+ opts.use_external_mip_script is not None or
opts.prealloc_wipe_disks is not None):
ToStderr("Please give at least one of the parameters.")
return 1
else:
opts.reserved_lvs = utils.UnescapeAndSplit(opts.reserved_lvs, sep=",")
+ if opts.master_netmask is not None:
+ try:
+ opts.master_netmask = int(opts.master_netmask)
+ except ValueError:
+ ToStderr("The --master-netmask option expects an int parameter.")
+ return 1
+
+ ext_ip_script = opts.use_external_mip_script
+
op = opcodes.OpClusterSetParams(vg_name=vg_name,
drbd_helper=drbd_helper,
enabled_hypervisors=hvlist,
default_iallocator=opts.default_iallocator,
prealloc_wipe_disks=opts.prealloc_wipe_disks,
master_netdev=opts.master_netdev,
- reserved_lvs=opts.reserved_lvs)
+ master_netmask=opts.master_netmask,
+ reserved_lvs=opts.reserved_lvs,
+ use_external_mip_script=ext_ip_script,
+ )
SubmitOpCode(op, opts=opts)
return 0
"init": (
InitCluster, [ArgHost(min=1, max=1)],
[BACKEND_OPT, CP_SIZE_OPT, ENABLED_HV_OPT, GLOBAL_FILEDIR_OPT,
- HVLIST_OPT, MAC_PREFIX_OPT, MASTER_NETDEV_OPT, NIC_PARAMS_OPT,
- NOLVM_STORAGE_OPT, NOMODIFY_ETCHOSTS_OPT, NOMODIFY_SSH_SETUP_OPT,
- SECONDARY_IP_OPT, VG_NAME_OPT, MAINTAIN_NODE_HEALTH_OPT,
- UIDPOOL_OPT, DRBD_HELPER_OPT, NODRBD_STORAGE_OPT,
+ HVLIST_OPT, MAC_PREFIX_OPT, MASTER_NETDEV_OPT, MASTER_NETMASK_OPT,
+ NIC_PARAMS_OPT, NOLVM_STORAGE_OPT, NOMODIFY_ETCHOSTS_OPT,
+ NOMODIFY_SSH_SETUP_OPT, SECONDARY_IP_OPT, VG_NAME_OPT,
+ MAINTAIN_NODE_HEALTH_OPT, UIDPOOL_OPT, DRBD_HELPER_OPT, NODRBD_STORAGE_OPT,
DEFAULT_IALLOCATOR_OPT, PRIMARY_IP_VERSION_OPT, PREALLOC_WIPE_DISKS_OPT,
- NODE_PARAMS_OPT, GLOBAL_SHARED_FILEDIR_OPT],
+ NODE_PARAMS_OPT, GLOBAL_SHARED_FILEDIR_OPT, USE_EXTERNAL_MIP_SCRIPT],
"[opts...] <cluster_name>", "Initialises a new cluster configuration"),
"destroy": (
DestroyCluster, ARGS_NONE, [YES_DOIT_OPT],
"verify": (
VerifyCluster, ARGS_NONE,
[VERBOSE_OPT, DEBUG_SIMERR_OPT, ERROR_CODES_OPT, NONPLUS1_OPT,
- DRY_RUN_OPT, PRIORITY_OPT, NODEGROUP_OPT],
+ DRY_RUN_OPT, PRIORITY_OPT, NODEGROUP_OPT, IGNORE_ERRORS_OPT],
"", "Does a check on the cluster configuration"),
"verify-disks": (
VerifyDisks, ARGS_NONE, [PRIORITY_OPT],
"modify": (
SetClusterParams, ARGS_NONE,
[BACKEND_OPT, CP_SIZE_OPT, ENABLED_HV_OPT, HVLIST_OPT, MASTER_NETDEV_OPT,
- NIC_PARAMS_OPT, NOLVM_STORAGE_OPT, VG_NAME_OPT, MAINTAIN_NODE_HEALTH_OPT,
- UIDPOOL_OPT, ADD_UIDS_OPT, REMOVE_UIDS_OPT, DRBD_HELPER_OPT,
- NODRBD_STORAGE_OPT, DEFAULT_IALLOCATOR_OPT, RESERVED_LVS_OPT,
- DRY_RUN_OPT, PRIORITY_OPT, PREALLOC_WIPE_DISKS_OPT, NODE_PARAMS_OPT],
+ MASTER_NETMASK_OPT, NIC_PARAMS_OPT, NOLVM_STORAGE_OPT, VG_NAME_OPT,
+ MAINTAIN_NODE_HEALTH_OPT, UIDPOOL_OPT, ADD_UIDS_OPT, REMOVE_UIDS_OPT,
+ DRBD_HELPER_OPT, NODRBD_STORAGE_OPT, DEFAULT_IALLOCATOR_OPT,
+ RESERVED_LVS_OPT, DRY_RUN_OPT, PRIORITY_OPT, PREALLOC_WIPE_DISKS_OPT,
+ NODE_PARAMS_OPT, USE_EXTERNAL_MIP_SCRIPT],
"[opts...]",
"Alters the parameters of the cluster"),
"renew-crypto": (
RenewCrypto, ARGS_NONE,
[NEW_CLUSTER_CERT_OPT, NEW_RAPI_CERT_OPT, RAPI_CERT_OPT,
NEW_CONFD_HMAC_KEY_OPT, FORCE_OPT,
- NEW_CLUSTER_DOMAIN_SECRET_OPT, CLUSTER_DOMAIN_SECRET_OPT],
+ NEW_CLUSTER_DOMAIN_SECRET_OPT, CLUSTER_DOMAIN_SECRET_OPT,
+ NEW_SPICE_CERT_OPT, SPICE_CERT_OPT, SPICE_CACERT_OPT],
"[opts...]",
"Renews cluster certificates, keys and secrets"),
"epo": (