Replacing Witnesses of Multiple ROBO Clusters with a Single Shared Witness
You can replace witnesses of multiple ROBO clusters with a single shared witness.
Here is an example for replacing in batches, multiple witnesses of ROBO clusters with a single shared witness:
def replaceWitnessInBatch(si, vscs, witness, clusterRefs): """ Replace witness with the same Shared witness in batches for for multiple robo clusters in one operation. Requirements: 1. The candidate cluster must be vSAN robo cluster. 2. There is no network isolation between witness and the multiple clusters given. """ checkCompatibility(si, vscs, clusterRefs, witness) for cluster in clusterRefs: if len(vscs.GetWitnessHosts(cluster)) != 1: msg = "ERROR: cluster %s is not a robo cluster" % cluster.name sys.exit(msg) print("Replacing the old witness(es) with shared witness %s" \ " for clusters: %s" % (witness.name, [cluster.name for cluster in clusterRefs])) spec = vim.vsan.VsanVcStretchedClusterConfigSpec( witnessHost = witness, clusters = [vim.cluster.VsanStretchedClusterConfig( cluster = cluster ) for cluster in clusterRefs] ) replaceWitnessTask = vscs.ReplaceWitnessHostForClusters(spec) vsanapiutils.WaitForTasks([replaceWitnessTask], si) def removeWitnessForClusters(si, vscs, witness, clusterRefs): totalTasks = [] for cluster in clusterRefs: print("Removing witness %s from cluster %s" % \ (witness.name, cluster.name)) removeTask = vscs.RemoveWitnessHost(cluster, witness) totalTasks.append(vsanapiutils.ConvertVsanTaskToVcTask( removeTask, si._stub)) vsanapiutils.WaitForTasks(totalTasks, si) def getWitnessClusters(si, vscs, witness): clusterNames = [] getWitnessClustrs = vscs.QueryWitnessHostClusterInfo(witness) for cluster in getWitnessClustrs: clusterMo = vim.ClusterComputeResource(cluster.cluster._moId, si._stub) clusterNames.append(clusterMo.name) return clusterNames class LogWitnessStatus(object): def __init__(self, si, vscs, witness): self.si = si self.vscs = vscs self.witness = witness def __enter__(self): print("Before Ops: shared witness %s has joined the following clusters:" " %s" % (self.witness.name, getWitnessClusters(self.si, self.vscs, self.witness))) def __exit__(self, *a): print("After Ops: Now shared witness %s has joined the following" " clusters: %s" % (self.witness.name, getWitnessClusters(self.si, self.vscs, self.witness))) def main(): args = GetArgs() if args.password: password = args.password else: password = getpass.getpass(prompt='Enter password for host %s and ' 'user %s: ' % (args.host,args.user)) # For python 2.7.9 and later, the default SSL context has more strict # connection handshaking rule. We may need turn off the hostname checking # and client side cert verification. context = None if sys.version_info[:3] > (2,7,8): context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE si = SmartConnect(host=args.host, user=args.user, pwd=password, port=int(args.port), sslContext=context) atexit.register(Disconnect, si) # Detecting whether the host is vCenter or ESXi. aboutInfo = si.content.about apiVersion = vsanapiutils.GetLatestVmodlVersion(args.host) if aboutInfo.apiType == 'VirtualCenter': majorApiVersion = aboutInfo.apiVersion if LooseVersion(majorApiVersion) < LooseVersion('7.0.1'): msg = "The Virtual Center with version %s (lower than 7.0U1) is not "\ "supported." % aboutInfo.apiVersion sys.exit(msg) # Get vSAN health system from the vCenter Managed Object references. vcMos = vsanapiutils.GetVsanVcMos( si._stub, context=context, version=apiVersion) vscs = vcMos['vsan-stretched-cluster-system'] witness = getComputeInstance(args.witness, si) if not witness: msg = 'Given witness host %s is not found in %s' % \ (args.witness, args.vc) sys.exit(msg) witness = witness.host[0] allClusters= [] if args.roboClusters: roboClusters = [clusterName.strip() for clusterName \ in args.roboClusters.split(',')] roboClusters = getClusterInstances(roboClusters, si) allClusters.extend(roboClusters) with LogWitnessStatus(si, vscs, witness): replaceWitnessInBatch(si, vscs, witness, roboClusters) if args.normalClusters: twoNodesClusters = [clusterName.strip() for clusterName \ in args.normalClusters.split(',')] twoNodesClusters = getClusterInstances(twoNodesClusters, si) allClusters.extend(twoNodesClusters) with LogWitnessStatus(si, vscs, witness): convertToRoboClusterInBatch(si, vscs, witness, twoNodesClusters) with LogWitnessStatus(si, vscs, witness): removeWitnessForClusters(si, vscs, witness, allClusters) else: print('Remote host should be a Virtual Center ') return -1