def activate_cluster(self, cluster, grand_cluster, enabled=True): """activate the cluster with the grand cluster""" if grand_cluster not in self.get_clusters(): raise HelixException( "grand cluster {0} does not exist".format(grand_cluster)) raise NotImplementedError
def _post_payload(host, path, data, **kwargs): """generic function to handle posting data :rtype : return body of page :param host: host to send data to :param path: path to interact with :param data: data to send :param kwargs: additional keyword args """ if "http://" not in host: host = "http://{0}".format(host) res = Resource(host) payload = "jsonParameters={0}".format(json.dumps(data)) for key, value in kwargs.items(): payload += '&{0}={1}'.format(key, json.dumps(value)) headers = {"Content-Type": "application/json"} # print "path is %s" % path page = res.post(path=path, payload=payload, headers=headers) body = page.body_string() if body: body = json.loads(body) if isinstance(body, dict) and "ERROR" in body: raise HelixException(body["ERROR"]) # test what was returned, see if any exceptions need to be raise # if not body: # raise HelixException("body for path {0} is empty".format(path)) # else: # print "BODY IS EMPTY FOR ", path # print "BODY is %s." % body return body
def get_instances(host, cluster): """get list of instances registered to the cluster""" if not cluster: raise HelixException("Cluster must be set before " "calling this function") return _get_page(host, "/clusters/{0}/instances".format(cluster))[ "instanceInfo"]
def get_external_view(host, cluster, resource): """return the external view for a given cluster and resource""" if resource not in get_resource_groups(host, cluster): raise HelixException( "{0} is not a resource group of {1}".format(resource, cluster)) return _get_page(host, "/clusters/{0}/resourceGroups/{1}/externalView".format( cluster, resource))["mapFields"]
def get_resource_group(host, cluster, resource): """ gets the ideal state of the specified resource group of the current cluster""" if resource not in get_resource_groups(host, cluster): raise HelixException( "{0} is not a resource group of {1}".format(resource, cluster)) return _get_page(host, "/clusters/{0}/resourceGroups/{1}".format(cluster, resource))
def _get_ideal_state(self, cluster, resource): """ gets the ideal state of the specified resource group of the current cluster""" if resource not in self.get_resource_groups(cluster): raise HelixException("{0} is not a resource group of {1}".format( resource, cluster)) return self._get_resource_group(cluster, resource)["mapFields"]
def enable_instance(self, instance, enabled=True): """enable instance, assumes instance a participant object""" ident = None if isinstance(instance, Participant): ident = instance.ident elif isinstance(instance, str): ident = instance else: raise HelixException("Instance must be a string or participant") return self.functions.enable_instance(self.cluster, ident, enabled)
def _get_external_view(self, cluster, resource): """return the external view for a given cluster and resource""" if resource not in self.get_resource_groups(cluster): raise HelixException("{0} is not a resource group of {1}".format( resource, cluster)) data, stat = self.zk.get( self._build_path( EXTERNAL_VIEW_STATE_PATH.format(clusterName=cluster, resourceName=resource))) return (json.loads(data)["mapFields"], stat)
def del_instance_tag(self, instance, tag): ident = None if isinstance(instance, Participant): ident = instance.ident elif isinstance(instance, str): ident = instance else: raise HelixException("Instance must be a string or participant") return self.functions.del_instance_tag(self.cluster, ident, tag)
def _get_page(self, path): """if we're specifying a cluster then verify that a cluster is set""" res = Resource(self.host) page = res.get(path=path) data = page.body_string() body = None try: body = json.loads(data) except ValueError: body = json.loads(data[:-3]) # test what was returned, see if any exceptions need to be raise if not body: raise HelixException("body for path {0} is empty".format(path)) if isinstance(body, dict) and "ERROR" in body: raise HelixException(body["ERROR"]) return body
def add_resource_tag(self, resource, tag): """add a tag to a resource""" resource_name = None if isinstance(resource, ResourceGroup): resource_name = resource.name elif isinstance(resource, str): resource_name = resource else: raise HelixException("Resource must be resource object or string") return self.functions.add_resource_tag(self.cluster, resource_name, tag)
def enable_resource(self, resource, enabled=True): """enable/disable resource""" resource_name = None if isinstance(resource, ResourceGroup): resource_name = resource.name elif isinstance(resource, str): resource_name = resource else: raise HelixException( "Resource must be a string or a resource group object") return self.functions.enable_resource(self.cluster, resource_name, enabled)
def enable_partition(self, resource, partition, instance, enabled=True): """enable partition, assumes instance and partition are helix objects""" ident = None part_id = None if isinstance(instance, Participant): ident = instance.ident elif isinstance(instance, str): ident = instance else: raise HelixException("Instance must be a string or participant") if isinstance(partition, Partition): part_id = partition.name elif isinstance(partition, str): part_id = partition else: raise HelixException("Partition must be a string or partition") return self.functions.enable_partition(self.cluster, resource, part_id, ident, enabled)
def rebalance(self, cluster, resource, replicas, key=""): """rebalance the given resource group""" if resource not in self.get_resource_groups(cluster): raise HelixException("{0} is not a resource group of {1}".format( resource, cluster)) data = {"command": "rebalance", "replicas": replicas} if key: data["key"] = key page = self._post_payload( "/clusters/{0}/resourceGroups/{1}/idealState".format( cluster, resource), data) return page
def _get_resource_group(self, cluster, resource): """ gets the ideal state of the specified resource group of the current cluster""" if resource not in self.get_resource_groups(cluster): raise HelixException( "{resource} is not a resource group of {cluster}".format( resource=resource, cluster=cluster)) data, stat = self.zk.get( self._build_path( RESOURCE_IDEAL_STATE_PATH.format(clusterName=cluster, resourceName=resource))) return (json.loads(data), stat)
def activate_cluster(self, cluster, grand_cluster, enabled=True): """activate the cluster with the grand cluster""" if grand_cluster not in self.get_clusters(): raise HelixException( "grand cluster {0} does not exist".format(grand_cluster)) data = {'command': 'activateCluster', 'grandCluster': grand_cluster} if enabled: data["enabled"] = "true" else: data["enabled"] = "false" page = self._post_payload("/clusters/{0}".format(cluster), data) return page
def rebalance(self, cluster, resource, replicas, key=""): """rebalance the given resource group""" if resource not in self.get_resource_groups(cluster): raise HelixException("{0} is not a resource group of {1}".format( resource, cluster)) # TODO: key usage is currently not supported. if not key == "": raise NotImplementedError resource_data, resource_meta = self._get_resource_group( cluster, resource) resource_data["simpleFields"]["REPLICAS"] = replicas self.zk.set( self._build_path( RESOURCE_IDEAL_STATE_PATH.format(clusterName=cluster, resourceName=resource)), json.dumps(resource_data)) return True
def get_instances(self, cluster): """get list of instances registered to the cluster""" if not cluster: raise HelixException("Cluster must be set before " "calling this function") instances = [] for instance in self._list_path( self._build_path( PARTICIPANTS_CONFIG_PATH.format(clusterName=cluster))): instance_data = json.loads( self.zk.get( self._build_path( PARTICIPANT_CONFIG_PATH.format( clusterName=cluster, instanceName=instance)))[0]) if self.zk.exists( self._build_path( LIVE_INSTANCE_PATH.format(clusterName=cluster, instanceName=instance))): instance_data["simpleFields"]["Alive"] = "true" else: instance_data["simpleFields"]["Alive"] = "false" instances.append(instance_data) return instances
def external_view(self, value): """setter for external view""" raise HelixException("External View cannot be modified!")
def ideal_state(self, value): """setter for ideal state""" raise HelixException("Cannot adjust Ideal State in this manner")
def participants(self, value): raise HelixException("Participants cannot added in this fashion!")
def disabled_partitions(self, value): raise HelixException("Partitions must be disabled on a cluster object")
def resources(self, value): """ensure an exception is raise on an attempt to set resource groups""" raise HelixException("Resource groups cannont be added in this manner")
def add_partition(self, part): """add a partition to this resource group""" if not isinstance(part, partition.Partition): raise HelixException("Argument part must be Partition or subclass") self.partitions[part.name] = part
def tags(self, value): """ensure an exception is raise on an attempt to set tags this way""" raise HelixException("Tags must be set on a cluster object")