def __init__(self, res_id): DataStoreObject.__init__(self) self._id = Id.parse_id(res_id) self._entity_type = self._id.entity_type self._agent_name = self._id.agent_name self._attribute_name = self._id.attribute self._attribute_value = self._id.attribute_value
def facts(self, resource_id, timeout = 10, wait = True): """ Get facts about a resource """ id_obj = Id.parse_id(resource_id) request = {"id" : resource_id} topic = 'resources.%s.%s' % (id_obj.agent_name, id_obj.entity_type) self._mq_send(topic, "FACTS", request) self._stack["facts"] = None if wait: stop = time.time() + timeout while self._stack["facts"] is None and stop > time.time(): time.sleep(0.1) return self._stack["facts"] return None
def status(self, resource_id, timeout = 10): """ Check the state of a resource """ self._report("Requesting status of %s" % resource_id) id_obj = Id.parse_id(resource_id) request = {"id" : resource_id} topic = 'resources.%s.%s' % (id_obj.agent_name, id_obj.entity_type) self._mq_send(topic, "STATUS", request) self._stack["status"] = None stop = time.time() + timeout while self._stack["status"] is None and stop > time.time(): time.sleep(0.1) return self._stack["status"]
def poll_facts(self, resource_id): """ Send out a request to receive facts """ if resource_id in self._fact_poll and (self._fact_poll[resource_id] + 60) > time.time(): return res_id = Id.parse_id(resource_id) # fetch the last deployed resource resource = DataStore.instance().get(Resource, resource_id) if resource is None: return versions = [v.version for v in resource.versions] sorted(versions) version = versions[-1] data = {} for v in resource.versions: if version == v.version: data = v.data break request = {"id" : resource_id, "resource": data, "operation" : "FACTS"} topic = 'resources.%s.%s' % (res_id.agent_name, res_id.entity_type) msg = amqp.Message(json.dumps(request)) msg.content_type = "application/json" msg.relpy_to = self._stomp._queue_name self._stomp._channel.basic_publish(msg, exchange = self._stomp._exchange_name, routing_key = topic) self._fact_poll[resource_id] = time.time()
def on_message(self, msg): """ Receive a new file """ message = json.loads(msg.body) if "operation" in message: operation = message["operation"] else: return if operation == "FACTS_REPLY": if "code" in message and message["code"] != 200: self._logger.error("Received a 404 message on a facts reply. " + str(message)) return if "facts" in message: facts = message['facts'] for subject,facts in message['facts'].items(): self._logger.info("Received facts from %s" % subject) for fact in facts: value = facts[fact] if not isinstance(value, str): value = json.dumps(value) fact_obj = Fact() fact_obj.value_time = time.time() fact_obj.resource_id = Id.parse_id(subject) fact_obj.name = fact fact_obj.value = value fact_obj.entity_type = fact_obj.resource_id.entity_type fact_obj.save() else: self._logger.error("No facts in message: " + str(message)) elif operation == "PONG": if "hostname" not in message: self._logger.error("Invalid PONG heartbeat received") return for host in message["hostname"]: h = Agent(host) h.save() elif operation == "UPDATED": if "id" not in message or "version" not in message: self._logger.error("Invalid UPDATED operation") return version = DataStore.instance().get(Version, message['id']) if version is not None: version.mark_updated() version.save() elif operation == "UPDATE": # ignore pass elif operation == "FACTS": pass else: self._logger.debug("Received message with unknown operation. operation = %s" % str(operation))
def _handle_op(self, operation, message): """ Handle an operation """ if operation == "PING": LOGGER.info("Got ping request, sending pong back") response = {"hostname" : self._hostnames } self._mq_send("control", "PONG", response) elif operation == "UPDATE": LOGGER.debug("Received update for %s", message["resource"]["id"]) resource = Resource.deserialize(message["resource"]) self.update(resource) elif operation == "UPDATED": rid = Id.parse_id(message["id"]) version = message["version"] reload = message["reload"] self._dm.resource_update(rid.resource_str(), version, reload) elif operation == "STATUS": resource = Id.parse_id(message["id"]).get_instance() if resource is None: self._mq_send("control", "STATUS_REPLY", {"code" : 404}) return try: provider = Commander.get_provider(self, resource.id) except Exception: LOGGER.exception("Unable to find a handler for %s" % resource) try: result = provider.check_resource(resource) self._mq_send("control", "STATUS_REPLY", result) except Exception: LOGGER.exception("Unable to check status of %s" % resource) self._mq_send("control", "STATUS_REPLY", {"code" : 404}) elif operation == "FACTS": resource_id = Id.parse_id(message["id"]) try: resource = Resource.deserialize(message["resource"]) provider = Commander.get_provider(self, resource_id) try: result = provider.facts(resource) response = {"operation" : "FACTS_REPLY", "subject" : str(resource_id), "facts" : result} self._mq_send("control", "FACTS_REPLY", response) except Exception: LOGGER.exception("Unable to retrieve fact") self._mq_send("control", "FACTS_REPLY", {"subject" : str(resource_id), "code": 404}) except Exception: LOGGER.exception("Unable to find a handler for %s" % resource_id) elif operation == "QUEUE": response = {"queue" : ["%s,v=%d" % (x.id, x.version) for x in self._queue.all()]} self._mq_send("control", "QUEUE_REPLY", response) elif operation == "DEPLOY": self.deploy_config() elif operation == "INFO": response = {"threads" : [x.name for x in enumerate()], "queue length" : self._queue.size(), "queue ready length" : self._queue.ready_size(), } self._mq_send("control", "INFO_REPLY", response) elif operation == "DUMP": LOGGER.info("Dumping!") self._queue.dump() elif operation == "MODULE_UPDATE": version = message["version"] modules = message["modules"] self._loader.deploy_version(version, modules)