def update_ipmi(self, request): attrs = [{ 'key': 'bootstrap', 'subkey': 'mac', 'value': request.hwaddr, }, { 'key': 'port-nic-eth', 'subkey': 'mac', 'number': 1, 'value': request.hwaddr, }] server = clusto.get_entities(attrs=attrs) if not server: return try: server = server[0] if request.options.get('vendor_class_id', None) == 'udhcp 0.9.9-pre': # This is an IPMI request #logging.debug('Associating IPMI %s %s' % (request.hwaddr, server.name)) server.set_port_attr('nic-eth', 1, 'ipmi-mac', request.hwaddr) else: #logging.debug('Associating physical %s %s' % (requst.hwaddr, server.name)) server.set_port_attr('nic-eth', 1, 'mac', request.hwaddr) except: log.error('Error updating server MAC: %s' % format_exc())
def get_ip_manager(cls, ip): """return a valid ip manager for the given ip. @param ip: the ip @type ip: integer, string, or IPy object @return: the appropriate IP manager from the clusto database """ ipman = None if isinstance(ip, Attribute): ipman = ip.entity return Driver(ipman) for ipmantest in clusto.get_entities(clusto_drivers=[cls]): try: ipmantest.ensure_type(ip) except ResourceTypeException: continue ipman = Driver(ipmantest) break if not ipman: raise ResourceException(u"No resource manager for %s exists." % str(ip)) return ipman
def run(self, args): if args.clusto_type is None: clusto_types = [] else: clusto_types = [args.clusto_type] for entity in clusto.get_entities(clusto_types=clusto_types): print entity.name
def get_by_hostname(hostname): """ Lookup an entity by its hostname. Returns a list of all entities that have the hostname. """ primary_hostname = clusto.get_entities(attrs=[{ 'subkey': 'hostname', 'value' : hostname, }]) hostname_alias = clusto.get_entities(attrs=[{ 'subkey': 'hostname-alias', 'value' : hostname, }]) return primary_hostname + hostname_alias
def get_pdu_hostnames(request): """Returns a list of hostnames for all hosts with a driver of LindenPDU. """ pdus = clusto.get_entities(clusto_drivers=[llclusto.drivers.LindenPDU]) return [pdu.hostname for pdu in pdus if pdu.hostname.lower() != 'missing']
def update_racks(): result = {} for datacenter in clusto.get_entities(clusto_types=["datacenter"]): for rack in datacenter.contents(clusto_types=["rack"]): devices = [] for ru in range(42, 0, -1): device = rack.get_device_in(ru) if device: devices.append( ( ru, device.name, device.type, " ".join([x.name for x in device.parents(clusto_types=["pool"])]), ) ) else: devices.append((ru, None, None, "")) if not datacenter.name in result: result[datacenter.name] = [] result[datacenter.name].append((rack.name, devices)) result[datacenter.name].sort(key=lambda x: x[0]) result = json.dumps(result) file("/home/synack/src/clusto-viz/result.json", "w").write(result)
def get_by_hostname(hostname): """ Lookup an entity by its hostname. Returns a list of all entities that have the hostname. """ primary_hostname = clusto.get_entities(attrs=[{ 'subkey': 'hostname', 'value': hostname, }]) hostname_alias = clusto.get_entities(attrs=[{ 'subkey': 'hostname-alias', 'value': hostname, }]) return primary_hostname + hostname_alias
def run(self, args): servers = dict([(x.name, x) for x in clusto.get_entities(clusto_types=['server']) if x.name != 'default']) # Don't even consider the 'default' object. instances = [] reasons = {} http = httplib2.Http() http.add_credentials(*os.environ['AMAZINGHORSE_CREDS'].split(':', 1)) for region in ('us-east-1', 'us-west-1'): resp, content = http.request('https://amazinghorse.simplegeo.com:4430/aws/ec2/%s/instance/' % region) for instance in json.loads(content): if instance['state'] == 'running': instances.append(instance['id']) else: if 'reason' in instance: reasons[instance['id']] = instance['reason'] output = [] for server in servers: if not server in instances: print 'Instance: %s' % server print 'IP: %s' % ' '.join(servers[server].attr_values(key='ip', subkey='ipstring')) print 'Parents: %s' % ' '.join([x.name for x in servers[server].parents()]) if server in reasons: print 'Termination reason: %s' % reasons[server] clusto.delete_entity(servers[server].entity)
def update_count(): conn = sqlite3.connect("/home/synack/src/clusto-viz/pools.db") c = conn.cursor() now = int(time.time()) for pool in clusto.get_entities(clusto_types=["pool"]): c.execute("INSERT INTO counts(name, ts, count) VALUES (?, ?, ?)", (pool.name, now, len(pool.contents()))) conn.commit() c.close()
def handle_discover(self, request): if conf("dhcp.update_ipmi"): self.update_ipmi(request) attrs = [{"key": "port-nic-eth", "subkey": "mac", "number": 1, "value": request.hwaddr}] server = clusto.get_entities(attrs=attrs) if not server: return if len(server) > 1: log.warning( "More than one server with address %s: %s" % (request.hwaddr, ", ".join([x.name for x in server])) ) return server = server[0] enabled = server.attrs(key="dhcp", subkey="enabled", merge_container_attrs=True) if not enabled or not enabled[0].value: log.info("DHCP not enabled for %s" % server.name) return ips = defaultdict(dict) for attr in server.attrs(key="ip"): ips[attr.number][attr.subkey] = attr.value for num, ip in ips.items(): if IP(ip["ipstring"]).iptype() != "PRIVATE": del ips[num] if not ips: log.info("No private IP assigned for %s" % server.name) return ip = ips.values().pop() ipman = dict([(x.key, x.value) for x in ip["manager"].attrs(subkey="property")]) # ipman = dict([(x['key'], x['value']) for x in clusto.get_ip_manager(ip).attrs() if x['subkey'] == 'property']) ipy = IP("%s/%s" % (ip["ipstring"], ipman["netmask"]), make_net=True) options = { "server_id": self.server_id, "lease_time": 3600, "renewal_time": 1600, "subnet_mask": ipman["netmask"], "broadcast_address": ipy.broadcast().strNormal(), "router": ipman["gateway"], "hostname": server.hostname, } log.info("Sending offer to %s, options: %s" % (server.name, options)) for attr in server.attrs(key="dhcp", merge_container_attrs=True): options[attr.subkey] = attr.value response = DHCPResponse(type="offer", offerip=ip["ipstring"], options=options, request=request) self.offers[request.packet.chaddr] = response self.send("255.255.255.255", response.build())
def _find_elb(self, name): entities = clusto.get_entities(attrs=({'key': 'elb', 'subkey': 'name', 'value': name},)) if len(entities) < 1: raise LookupError('No ELB named %s found!' % name) elif len(entities) > 1: raise LookupError('Multiple ELBs named %s found!' % name) return entities[0]
def make_all_ec2_objects(aws_access_key_id=None, aws_secret_access_key=None): ec2man = clusto.get_entities(clusto_types=[clusto.drivers.EC2VMManager]) if not ec2man: if not aws_access_key_id and not aws_secret_access_key: raise Exception("you must specify both an aws_access_key_id and an " "aws_secret_access_key if you don't already have " "an EC2VMManager") ec2man = clusto.drivers.EC2VMManager('ec2vmman', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) else: ec2man = ec2man.pop() ec2ipman = clusto.get_entities(clusto_types=[clusto.drivers.EC2IPManager]) if not ec2ipman: if not aws_access_key_id and not aws_secret_access_key: raise Exception("you must specify both an aws_access_key_id and an " "aws_secret_access_key if you don't already have " "an EC2IPManager") ec2ipman = clusto.drivers.EC2IPManager('ec2ipman', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) else: ec2ipman = ec2ipman.pop() conn = ec2man._ec2_connection() for region in conn.get_all_regions(): curconn = ec2man._ec2_connection(region.name) region_entity = clusto.get_or_create(region.name, clusto.drivers.EC2Region, region=region.name) for zone in curconn.get_all_zones(): zone_entity = clusto.get_or_create(zone.name, clusto.drivers.EC2Zone, placement=zone.name) if zone_entity not in region_entity: region_entity.insert(zone_entity)
def search(self, request, match): query = request.params.get('q', None) if not query: return Response(status=400, body='400 Bad Request\nNo query specified\n') result = [] for obj in clusto.get_entities(): if obj.name.find(query) != -1: result.append(unclusto(obj)) return dumps(request, result)
def list_host_states(request): """Gets a list of all defined host states. Returns: A list of host state names as strings. """ states = clusto.get_entities(clusto_drivers=[llclusto.drivers.HostState]) return [state.name for state in states]
def testAttributeOldVersionsInGetEntities(self): sl = [BasicServer('s' + str(x)) for x in range(10)] for n, s in enumerate(sl): s.add_attr(key='old', value="val") s.del_attrs(key='old') s.add_attr(key='new', value='foo') l=clusto.get_entities(attrs=[{'key':'old', 'value':'val'}]) self.assertEqual(l, [])
def testAttributeOldVersionsInGetEntities(self): sl = [BasicServer('s' + str(x)) for x in range(10)] for n, s in enumerate(sl): s.add_attr(key='old', value="val") s.del_attrs(key='old') s.add_attr(key='new', value='foo') l = clusto.get_entities(attrs=[{'key': 'old', 'value': 'val'}]) self.assertEqual(l, [])
def list(self): entities = clusto.get_entities(clusto_types=[AmazonELB]) if len(entities) < 1: print 'No ELB object found in Clusto.' return 0 else: sys.stdout.write('Name'.ljust(15)) sys.stdout.write('Clusto Name\n') for entity in entities: sys.stdout.write(entity.elb_name.ljust(15)) sys.stdout.write(entity.name) sys.stdout.write('\n')
def testGetEntitesWithAttrs(self): d1 = Driver('d1') d2 = Driver('d2') d3 = Driver('d3') d4 = Driver('d4') d1.add_attr('k1', 'test') d2.add_attr('k1', 'testA') d1.add_attr('k2', number=1, subkey='A', value=67) d3.add_attr('k3', number=True, value=d4) self.assertEqual(clusto.get_entities(attrs=[{'key': 'k2'}]), [d1]) self.assertEqual(sorted(clusto.get_entities(attrs=[{ 'key': 'k1' }])), sorted([d1, d2])) self.assertEqual(sorted(clusto.get_entities(attrs=[{ 'value': d4 }])), [d3]) self.assertEqual(clusto.get_entities(attrs=[{'value': 67}]), [d1]) self.assertEqual(sorted(clusto.get_entities(attrs=[{ 'number': 0 }])), sorted([d3])) self.assertEqual( clusto.get_entities(attrs=[{ 'subkey': 'A' }, { 'value': 'test' }]), [d1])
def list_log_event_types(request): """Returns a dictionary of log event types Returns: A dictionary keyed on the log event type name and valued on the description. Arguments: None """ event_types = clusto.get_entities(clusto_types=["logeventtype"]) return dict((event_type.name,event_type.description) for event_type in event_types)
def get_entities(self, request): kwargs = {'attrs': []} for k, v in request.params.items(): if k in ('format', 'callback'): continue v = loads(request, unquote_plus(v)) kwargs[str(k)] = v attrs = [] for attr in kwargs['attrs']: attrs.append(dict([(str(k), v) for k, v in attr.items()])) kwargs['attrs'] = attrs result = [unclusto(x) for x in clusto.get_entities(**kwargs)] return dumps(request, result)
def ngi_list_images(request): """Returns a list of all available NGI images Returns: A list of ngi image names as strings. Arguments: None Exceptions Raised: None """ return [image.name for image in clusto.get_entities(clusto_types=[llclusto.drivers.NGIImage])]
def testDeleteEntity(self): e1 = Entity.query().filter_by(name=u'e1').one() d = Driver(e1) d.add_attr('deltest1', 'test') d.add_attr('deltest1', 'testA') clusto.delete_entity(e1) self.assertEqual([], clusto.get_entities(names=['e1'])) self.assertEqual([], Driver.do_attr_query(key='deltest*', glob=True))
def set_dhcp_association(request, hostname, mac_address): """ Function that sets a hostname to a specified mac_address. Arguments: hostname -- The hostname of an entity. mac_address -- The mac_address of an entity. Exceptions Raised: JinxInvalidStateError -- More than one host had the specified hostname or mac address, or could not be found. """ hostname = hostname.lower() mac_address = mac_address.lower() servers = clusto.get_by_mac(mac_address) ipmi_hosts = clusto.get_entities(attrs=[{'subkey': 'ipmi_mac', 'value': mac_address}]) hosts = llclusto.get_by_hostname(hostname) if not servers and not ipmi_hosts: return HttpResponseInvalidState('Could not find any entities with MAC address: "%s".' % mac_address) try: clusto.begin_transaction() for host in hosts: for (port_type, port_num, ignore, ignore) in host.port_info_tuples: if host.get_hostname(port_type, port_num) == hostname: host.del_hostname(port_type, port_num) for server in servers: for (port_type, port_num, ignore, ignore) in server.port_info_tuples: if server.get_port_attr(port_type, port_num, "mac") == mac_address: server.set_hostname(hostname, port_type, port_num) for host in ipmi_hosts: ipmi = host.ipmi if ipmi[1] == mac_address: host.set_ipmi_info(hostname, ipmi[1]) clusto.commit() except: clusto.rollback_transaction() raise
def get_hosts_in_state(request, state): """Gets a list of all hosts in the specified state. Returns: A list of hostnames. Arguments: state -- The name of the state. Exceptions Raised: JinxInvalidStateError -- The specified state does not exist. Please see list_states() for a list of valid states. """ try: state = clusto.get_entities(names=[state], clusto_drivers=[llclusto.drivers.HostState])[0] return [host.hostname for host in state if host.hostname is not None] except IndexError: return HttpResponseInvalidState("State %s does not exist." % state)
def delete_dhcp_association(request, hostname, mac_address): """ Function that deletes a hostname from a specified mac_address. Arguments: hostname -- The hostname of an entity. mac_address -- The mac_address of an entity. Exceptions Raised: JinxInvalidStateError -- More than one host had the specified hostname or mac address, or could not be found. """ hostname = hostname.lower() mac_address = mac_address.lower() server = clusto.get_by_mac(mac_address) server_ipmi = clusto.get_entities(attrs=[{'subkey': 'ipmi_mac', 'value': mac_address}]) if len(server) < 1: if len(server_ipmi) < 1: return HttpResponseInvalidState('Could not find any entities with MAC address: "%s".' % mac_address) elif len(server_ipmi) > 1: return HttpResponseInvalidState('Found multiple IPMI entities with MAC address: "%s: %s".' % mac_address, server_ipmi) elif len(server) > 1: return HttpResponseInvalidState('Found multiple entities with MAC address: "%s: %s".' % mac_address, server) try: clusto.begin_transaction() if server: server = server[0] for (port_type, port_num, ignore, ignore) in server.port_info_tuples: if server.get_hostname(port_type, port_num) == hostname: server.del_hostname(port_type, port_num) if server_ipmi: server = server_ipmi[0] if server.ipmi[0] == hostname: server.del_ipmi_hostname() clusto.commit() except: clusto.rollback_transaction() raise
def ngi_get_all_associations(request): """Returns all hostnames and associated PGI image IDs. Returns: A dictionary mapping host names to PGI image IDs. Arguments: None Exceptions Raised: None """ host_images = {} for host in clusto.get_entities(attrs=[{'key': 'ngi_image'}]): host_images[host.hostname] = host.ngi_image.name return host_images
def list_host_image_associations(request): """Returns all hostnames and associated PGI image names. Returns: A dictionary keyed on hostnames and the values are the associated image name. Arguments: None Exceptions Raised: None """ host_images = {} for host in clusto.get_entities(attrs=[{"key": "pgi_image"}]): host_images[host.hostname] = host.pgi_image.name return host_images
def jinx_query_serial(request, serial_number): """ Returns information about a device by serial number. Arguments: serial_number -- The serial number of the device. Exceptions Raised: JinxInvalidStateError -- The requested rack_name could not be found. """ host = clusto.get_entities(attrs=[{'key': 'serial_number', \ 'subkey': 'property', \ 'value': serial_number }]) if host: return _get_device_info(request, host[0]) else: return HttpResponseInvalidState("Serial Number %s not found." % serial_number)
def list_servable_pgi_images(request): """Returns a list of servable PGI images stored on the PGI systemimagers. Returns: A list of pgi image names as strings. Arguments: None Exceptions Raised: None """ servable_images = [] for image in clusto.get_entities(clusto_types=[llclusto.drivers.PGIImage]): if len(image.get_si_servers_stored_on()) > 0: servable_images.append(image.name) return servable_images
def get_ip_managers(cls, ip): """return a list of valid ip managers for the given ip. @param ip: the ip @type ip: integer, string, or IPy object @return: a list of IP managers from the clusto database """ ipman = None if isinstance(ip, Attribute): ipman = ip.entity return Driver(ipman) ipmanagers = [] for ipman in clusto.get_entities(clusto_drivers=[cls]): try: ipman.ensure_type(ip) ipmanagers.append(Driver(ipman)) except ResourceTypeException: continue return ipmanagers
def update_ipmi(self, request): attrs = [ {"key": "bootstrap", "subkey": "mac", "value": request.hwaddr}, {"key": "port-nic-eth", "subkey": "mac", "number": 1, "value": request.hwaddr}, ] server = clusto.get_entities(attrs=attrs) if not server: return try: server = server[0] if request.options.get("vendor_class_id", None) == "udhcp 0.9.9-pre": # This is an IPMI request # logging.debug('Associating IPMI %s %s' % (request.hwaddr, server.name)) server.set_port_attr("nic-eth", 1, "ipmi-mac", request.hwaddr) else: # logging.debug('Associating physical %s %s' % (requst.hwaddr, server.name)) server.set_port_attr("nic-eth", 1, "mac", request.hwaddr) except: log.error("Error updating server MAC: %s" % format_exc())
def reconcile_additional_attrs(self): """ Will correct the number of any incorrectly set attributes from additional attributes that share the resourcemanager's attr_key. """ for ref in self.references(): thing = get_entities([ref.entity.name])[0] for attr in thing.attrs(self._attr_name): if not attr.number == ref.number: print 'Changing {0}\'s incorrect attribute...'.format(thing.name) thing.set_attr( key=attr.key, subkey=attr.subkey, # Replicate all values except the number. number=ref.number, value=attr.value ) thing.del_attrs( key=attr.key, subkey=attr.subkey, number=attr.number, value=attr.value )
def testGetEntitesWithAttrs(self): d1 = Driver('d1') d2 = Driver('d2') d3 = Driver('d3') d4 = Driver('d4') d1.add_attr('k1', 'test') d2.add_attr('k1', 'testA') d1.add_attr('k2', number=1, subkey='A', value=67) d3.add_attr('k3', number=True, value=d4) self.assertEqual(clusto.get_entities(attrs=[{'key':'k2'}]), [d1]) self.assertEqual(sorted(clusto.get_entities(attrs=[{'key':'k1'}])), sorted([d1,d2])) self.assertEqual(sorted(clusto.get_entities(attrs=[{'value':d4}])), [d3]) self.assertEqual(clusto.get_entities(attrs=[{'value':67}]), [d1]) self.assertEqual(sorted(clusto.get_entities(attrs=[{'number':0}])), sorted([d3])) self.assertEqual(clusto.get_entities(attrs=[{'subkey':'A'}, {'value':'test'}]), [d1])
def types_delegate(self, request, match): objtype = match.groupdict()['objtype'] result = [] for obj in clusto.get_entities(clusto_types=(objtype,)): result.append(unclusto(obj)) return dumps(request, result)
def handle_discover(self, request): if conf('dhcp.update_ipmi'): self.update_ipmi(request) attrs = [{ 'key': 'port-nic-eth', 'subkey': 'mac', 'number': 1, 'value': request.hwaddr, }] server = clusto.get_entities(attrs=attrs) if not server: return if len(server) > 1: log.warning('More than one server with address %s: %s' % (request.hwaddr, ', '.join([x.name for x in server]))) return server = server[0] enabled = server.attrs(key='dhcp', subkey='enabled', merge_container_attrs=True) if not enabled or not enabled[0].value: log.info('DHCP not enabled for %s' % server.name) return ips = defaultdict(dict) for attr in server.attrs(key='ip'): ips[attr.number][attr.subkey] = attr.value for num, ip in ips.items(): if IP(ip['ipstring']).iptype() != 'PRIVATE': del ips[num] if not ips: log.info('No private IP assigned for %s' % server.name) return ip = ips.values().pop() ipman = dict([(x.key, x.value) for x in ip['manager'].attrs(subkey='property')]) #ipman = dict([(x['key'], x['value']) for x in clusto.get_ip_manager(ip).attrs() if x['subkey'] == 'property']) ipy = IP('%s/%s' % (ip['ipstring'], ipman['netmask']), make_net=True) options = { 'server_id': self.server_id, 'lease_time': 3600, 'renewal_time': 1600, 'subnet_mask': ipman['netmask'], 'broadcast_address': ipy.broadcast().strNormal(), 'router': ipman['gateway'], 'hostname': server.hostname, } log.info('Sending offer to %s, options: %s' % (server.name, options)) for attr in server.attrs(key='dhcp', merge_container_attrs=True): options[attr.subkey] = attr.value response = DHCPResponse(type='offer', offerip=ip['ipstring'], options=options, request=request) self.offers[request.packet.chaddr] = response self.send('255.255.255.255', response.build())
def list(driver=None): """ Returns all entities, or (optionally) all entities of the given driver Example: .. code:: bash $ ${get} ${server_url}/entity/ [ ... ] HTTP: 200 Content-type: application/json Will list all entities Example: .. code:: bash $ ${get} ${server_url}/entity/clustometa [ "/clustometa/clustometa" ] HTTP: 200 Content-type: application/json Will list all entities that match the driver ``clustometa`` The following example should fail because there is no driver ``nondriver``: .. code:: bash $ ${get} ${server_url}/entity/nondriver "The requested driver \"nondriver\" does not exist" HTTP: 412 Content-type: application/json """ result = [] kwargs = {} mode = bottle.request.headers.get('Clusto-Mode', default='compact') headers = {} try: # Assignments are moved into the try block because of the int casting. current = int(bottle.request.headers.get('Clusto-Page', default='0')) per = int(bottle.request.headers.get('Clusto-Per-Page', default='50')) except TypeError as ve: return util.dumps('%s' % (ve, ), 400) for param in request.params.keys(): kwargs[param] = request.params.getall(param) if driver: if driver in clusto.driverlist: kwargs['clusto_drivers'] = [clusto.driverlist[driver]] else: return util.dumps( 'The requested driver "%s" does not exist' % (driver, ), 412) ents = clusto.get_entities(**kwargs) if current: ents, total = util.page(ents, current=current, per=per) headers['Clusto-Pages'] = total headers['Clusto-Per-Page'] = per headers['Clusto-Page'] = current for ent in ents: result.append(util.show(ent, mode)) return util.dumps(result, headers=headers)
def testGetEntities(self): d1 = Driver('d1') dv1 = Device('dv1') Location('l1') BasicDatacenter('dc1') namelist = ['e1', 'e2', 'dv1'] self.assertEqual( sorted([n.name for n in clusto.get_entities(names=namelist)]), sorted(namelist)) dl = [Driver] self.assertEqual( sorted([n.name for n in clusto.get_entities(clusto_drivers=dl)]), sorted(['d1', 'e1', 'e2', 'e3'])) tl = [Location, BasicDatacenter] self.assertEqual( sorted([n.name for n in clusto.get_entities(clusto_types=tl)]), sorted(['l1', 'dc1'])) p1 = Pool('p1') p2 = Pool('p2') p3 = Pool('p3') p4 = Pool('p4') s1 = BasicServer('s1') s2 = BasicServer('s2') s3 = BasicServer('s3') p1.insert(s1) p1.insert(s2) p2.insert(s2) p2.insert(s3) p2.insert(d1) p3.insert(s3) p3.insert(d1) p3.insert(s1) p4.insert(p3) self.assertEqual( sorted([s2, s3]), sorted( clusto.get_from_pools(pools=[p2], clusto_types=[BasicServer]))) self.assertEqual( sorted([s2]), sorted( clusto.get_from_pools(pools=[p2, 'p1'], clusto_types=[BasicServer]))) self.assertEqual( sorted([s3]), sorted( clusto.get_from_pools(pools=['p2', 'p3'], clusto_types=[BasicServer]))) self.assertEqual( sorted([s1]), sorted( clusto.get_from_pools(pools=['p4', 'p1'], clusto_types=[BasicServer])))
def list(driver=None): """ Lists all resource managers found in the clusto database. Optionally you can list all resource managers that match the given ``driver`` Examples: .. code:: bash $ ${post} -d 'name=zmanager' ${server_url}/resourcemanager/simplenamemanager { "attrs": [ ... ], "contents": [], "count": 0, "driver": "simplenamemanager", "name": "zmanager", "parents": [], "type": "resourcemanager" } HTTP: 201 Content-type: application/json The above will create a simple name manager called "zmanager" .. code:: bash $ ${get} ${server_url}/resourcemanager/ [ "/simpleentitynamemanager/testnames", "/simplenamemanager/zmanager" ] HTTP: 200 Content-type: application/json The above will list all resource managers in clusto, which should have "zmanager" .. code:: bash $ ${get} ${server_url}/resourcemanager/simpleentitynamemanager [ "/simpleentitynamemanager/testnames" ] HTTP: 200 Content-type: application/json Will list all resource managers of driver ``SimpleNameManager`` .. code:: bash $ ${get} ${server_url}/resourcemanager/notadriver "Not a valid driver \"notadriver\" (driver name notadriver doesn't exist.)" HTTP: 404 Content-type: application/json Will return a ``404`` error because that resource manager driver doesn't exist """ result = [] if driver: try: ents = clusto.get_entities(clusto_drivers=[driver]) except NameError as ne: return util.dumps( 'Not a valid driver "%s" (%s)' % (driver, ne,), 404 ) else: # Until we fix the ipmanager snafu, gotta check for both types ents = clusto.get_entities(clusto_types=['resourcemanager']) for ent in ents: # Kind of shitty way, but have to make sure these are all resource managers if issubclass(ent.__class__, drivers.resourcemanagers.ResourceManager): result.append(util.unclusto(ent)) return util.dumps(result)
def main(): global log parser = optparse.OptionParser(usage="%prog [options] clusto_query_string", version=__version__) parser.add_option('-v', '--verbose', action='count', default=0) parser.add_option('-f', '--formatter', default=r"%name", help='Formatter to use for printing, default "%default"') parser.add_option('--list-attributes', default=False, action='store_true', help='Print all the queryable attributes') parser.add_option('--clusto-config', default='/etc/clusto/clusto.conf', help='Path to clusto config file (default %default)') parser.add_option('--man', action="store_true", help="Show more detailed help") parser.add_option( '-m', '--merge-container-attrs', action='store_true', help="When showing attributes, merge in parents' attributes") opts, args = parser.parse_args() level = logging.WARNING if opts.verbose == 1: level = logging.INFO elif opts.verbose > 1: level = logging.DEBUG if opts.man: print(long_help) return 0 settings.merge_container_attrs = opts.merge_container_attrs conf = clusto.script_helper.load_config(opts.clusto_config) clusto.connect(conf) # clusto.connect screws up logging for all of its consumers, so we need # to init logging *after* calling clusto.connect log = logging.getLogger("clusto-query-logger") log.propagate = 0 handler = logging.StreamHandler() handler.setFormatter( logging.Formatter("%(asctime)s %(levelname)s: %(message)s")) handler.setLevel(level) log.addHandler(handler) log.setLevel(level) if opts.list_attributes: all_attrs = [it.attrs() for it in clusto.get_entities()] print("\n".join( sorted( set([ ".".join(map(str, (at.key, at.subkey))) for at in itertools.chain.from_iterable(all_attrs) ])))) return 0 if not args: parser.error("No query provided") raw_query = " ".join(args) log.info("Going to parse %r", raw_query) lexed_query = lex(raw_query) log.info("Lexed into %r", lexed_query) parsed_query, unparsed = parse_query(lexed_query) log.info("Parsed into %r", parsed_query) if unparsed: log.warning("Unparsed content: %r", unparsed) return 1 if os.environ.get('CLUSTO_TYPE_FILTER', None) is not None: def look_for_type(node): if isinstance(node, (Equality, Inequality)) and\ ('type' in node.parameters or 'clusto_type' in node.parameters) and\ 'server' in node.parameters: return True return False if not any(look_for_type(node) for node in parsed_query.visit_iter()): log.debug('Adding intersection with type=%s' % os.environ['CLUSTO_TYPE_FILTER']) parsed_query = Intersection( parsed_query, Equality('clusto_type', os.environ['CLUSTO_TYPE_FILTER'])) log.info('After intersection, parsed into %r', parsed_query) else: log.debug('Not adding type intersection') # fetch all the hosts format_template = EasierTemplate(opts.formatter) context = Context(clusto) for result_key in sorted( parsed_query.run(context.entity_map.keys(), context)): host = context.entity_map[result_key] print(format_template.substitute(HostFormatter(host, context))) return 0