def update_resource(self, resource_data): """ Update a resource. Broadcast it on the bus and store the update in the database. """ ds = DataStore.instance() resource = R.deserialize(resource_data) version = Version(resource.id) version.data = resource_data version.save() if not ds.contains(Resource, version.resource_id): res = Resource(version.resource_id) res.save() if not ds.contains(Agent, res.agent_name): agent = Agent(res.agent_name) agent.save() # broadcast topic = "%s.%s" % (resource.id.agent_name, resource.id.entity_type) msg = amqp.Message(json.dumps({"operation" : "UPDATE", "resource": resource_data})) msg.content_type = "application/json" self._channel.basic_publish(msg, exchange = self._exchange_name, routing_key = "resources.%s" % topic)
def __init__(self, config): self._config = config self._loader = CodeLoader(self._config["server"]["code_dir"]) self._logger = logging.getLogger(__class__.__name__) loglevel = self._config["server"]["loglevel"] numeric_level = getattr(logging, loglevel.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % loglevel) logging.basicConfig(filename=self._config["server"]["logfile"], filemode='w', level=numeric_level) self._logger.debug("Init server") self._stomp = None self._fact_poll = {} # open the fact store ds = DataStore.instance() ds.open(self._config["server"]["database"])
def get(self, resource_id): ds = DataStore.instance() resource = ds.get(Resource, resource_id) 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 content = "" if "hash" in data: file_path = os.path.join(self._server._config["server"]["storage"], data["hash"]) if os.path.exists(file_path): with open(file_path, "rb+") as fd: content = fd.read() self.render("resource.html", resource_id = resource_id, resource = resource, data = data, content = content)
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 get(self, agent_id): agent = DataStore.instance().get(Agent, agent_id) self.render("agent.html", agent_id = agent_id, agent = agent)
def get(self): self.render("index.html", db = DataStore.instance(), Agent = persistence.Agent)