def action(text=('m', 'Hello from the administration console!'), status=('s', 'success'), reloader=('r', '0')): """ Send messages and reload request to a browser connected to the appliance. """ # muck the reload flags around if reloader == '1' or reloader.lower() == 'true': reloader = True else: reloader = False # send out the message message(text, status, reloader)
def cleanup_reservations(command, bot): # check if timeout epoch_time = int(time.time()) # cancel reservation if older than 7 minutes (we fudge this in the tweet) if (command.updated + 420) < epoch_time: instance = db.session.query(Instances).filter_by(id=command.instance_id).first() if instance: instance.callback_url = "" instance.state = 1 instance.update() message("Canceled reservation on %s." % instance.name, "error", True) command.delete(command)
def action( text=('m', 'Hello from the administration console!'), status=('s', 'success'), reloader=('r', '0') ): """ Send messages and reload request to a browser connected to the appliance. """ # muck the reload flags around if reloader == '1' or reloader.lower() == 'true': reloader = True else: reloader = False # send out the message message(text, status, reloader)
def task(): # START # instances which have received payment are moved to starting instances = db.session.query(Instances).filter_by(state=2).all() for instance in instances: response = instance.start() if response['response'] == "success": message("Instance %s launched." % instance.name, "success", True) else: message("%s Unable to launch instance %s." % ( response['result']['message'], instance.name ), "error", True ) instance.message = response['result']['message'] instance.update() # NUDGE # instances in the process of starting are monitored and updated instances = db.session.query(Instances).filter_by(state=3).all() for instance in instances: response = instance.nudge() if response['response'] == "success": message("Instance %s is now running." % instance.name, "success", True) # RELIGHT # instances which have unpaused via payment instances = db.session.query(Instances).filter_by(state=6).all() # loop through them and do housekeeping for instance in instances: response = instance.housekeeping() # if instance isn't running if response['response'] == "error": message(response['result']['message'], "error", True) instance.message = response['result']['message'] instance.update() else: if response['result']['message'] != "": message(response['result']['message'], "success", True) return
def task(): # START # instances which have received payment are moved to starting instances = db.session.query(Instances).filter_by(state=2).all() for instance in instances: response = instance.start() if response['response'] == "success": message("Instance %s launched." % instance.name, "success", True) else: message( "%s Unable to launch instance %s." % (response['result']['message'], instance.name), "error", True) instance.message = response['result']['message'] instance.update() # NUDGE # instances in the process of starting are monitored and updated instances = db.session.query(Instances).filter_by(state=3).all() for instance in instances: response = instance.nudge() if response['response'] == "success": message("Instance %s is now running." % instance.name, "success", True) # RELIGHT # instances which have unpaused via payment instances = db.session.query(Instances).filter_by(state=6).all() # loop through them and do housekeeping for instance in instances: response = instance.housekeeping() # if instance isn't running if response['response'] == "error": message(response['result']['message'], "error", True) instance.message = response['result']['message'] instance.update() else: if response['result']['message'] != "": message(response['result']['message'], "success", True) return
def action(): """ Removes decomissioned and errant instances. Also takes out the trash occasionally. Cron: Every 15 minutes. """ # check appliance is ready to go - exit if not settings = Status().check_settings() if not settings['ngrok'] or not settings['openstack']: app.logger.error("Running trashman - appliance is not ready.") return action instances = db.session.query(Instances).filter_by(state=7).all() for instance in instances: response = instance.trashman() message(response['result']['message'], "success", True)
def address_handler(address_token): # look up address address = Addresses().get_by_token(address_token) # build the response response = {"response": "success", "result": {}} # check if we found an address that matches if address: # pull the instance out by id instance = Instances().get_by_id(address.instance_id) try: # find out how much we were paid amount = float(request.json['amount']) except: # bad stuff happens amount = 0 response['response'] = "error" response['result'] = "Amount not received or zero." app.logger.error( "A payment provider callback contains an invalid amount.") return jsonify(response), 401 # coin-op the instance instance_response = instance.coinop(amount) # indicate we were paid and reload the page message( "Instance %s received a payment of %s micro BTC." % (instance.name, int(amount * 1000000)), "success", True) app.logger.info( "Payment of amount=(%s) micro BTC received for instance=(%s)." % (int(amount * 1000000), instance.name)) # load response response['result'] = "acknowledged" return jsonify(response) else: app.logger.error( "A payment was recieved on an unused bitcoin address.") response['response'] = "error" response['result'] = "bitcoin address token not found" return jsonify(response), 401
def action(): """ Removes decomissioned and errant instances. Also takes out the trash occasionally. Cron: Every 15 minutes. """ # check appliance is ready to go - exit if not settings = Status().check_settings() if not settings['ngrok'] or not settings['openstack']: app.logger.error("Running trashman - appliance is not ready.") return action instances = db.session.query(Instances).filter_by(state=7).all() for instance in instances: response = instance.trashman() message(response['result']['message'], "success", True)
def cleanup_reservations(command, bot): # check if timeout epoch_time = int(time.time()) # cancel reservation if older than 7 minutes (we fudge this in the tweet) if (command.updated + 420) < epoch_time: instance = db.session.query(Instances).filter_by( id=command.instance_id).first() if instance: instance.callback_url = "" instance.state = 1 instance.update() message("Canceled reservation on %s." % instance.name, "error", True) command.delete(command)
def address_handler(address_token): # look up address address = Addresses().get_by_token(address_token) # build the response response = {"response": "success", "result": {}} # check if we found an address that matches if address: # pull the instance out by id instance = Instances().get_by_id(address.instance_id) try: # find out how much we were paid amount = float(request.json['amount']) except: # bad stuff happens amount = 0 response['response'] = "error" response['result'] = "Amount not received or zero." app.logger.error("A payment provider callback contains an invalid amount.") return jsonify(response), 401 # coin-op the instance instance_response = instance.coinop(amount) # indicate we were paid and reload the page message("Instance %s received a payment of %s micro BTC." % (instance.name, int(amount*1000000)), "success", True) app.logger.info("Payment of amount=(%s) micro BTC received for instance=(%s)." % (int(amount*1000000), instance.name)) # load response response['result'] = "acknowledged" return jsonify(response) else: app.logger.error("A payment was recieved on an unused bitcoin address.") response['response'] = "error" response['result'] = "bitcoin address token not found" return jsonify(response), 401
def action(): """ Provides housekeeping services including mix, pause and decomission. Cron: Every 5 minutes. """ # check appliance is ready to go - exit if not settings = Status().check_settings() if not settings['ngrok'] or not settings['openstack']: app.logger.error("Running housekeeper - appliance is not ready.") return action # MIXING # make sure we have mixed an instance for each flavor instances = Instances() flavors = Flavors.query.filter_by(installed=True, active=True).all() # loop through the flavors we have and mix an instance for flavor in flavors: response = instances.mix(flavor) if response['response'] != "success": message("Instance mixing failed. Something is wrong.") # HOUSEKEEPING # general houskeeping work including pausing, unpausing # runs on all currently running and suspended instances instances = db.session.query(Instances).filter(or_( Instances.state == 2, Instances.state == 4, Instances.state == 5 )).all() # loop through them and do housekeeping for instance in instances: response = instance.housekeeping() # if instance isn't running if response['response'] == "error": message(response['result']['message'], "error", True) else: if response['result']['message'] != "": message(response['result']['message'], "success", True)
def reserve_instance(command, bot): # default response response = {"response": "success", "result": {"message": ""}} # check quota if int( db.session.query(TweetCommands).filter_by( command="instance").count()) >= bot.max_instances: tweet_status( "Sorry @%s, I'm at my %s instance quota. Wait a bit and try again." % (user, bot.max_instances)) command.delete(command) response['response'], response[ 'result'] = "error", "Instance quota reached." return response # check the user doesn't have another instance already ic = db.session.query(TweetCommands).filter_by(command="instance", user=command.user).count() if ic > 1: tweet_status("Sorry, I only do %s instance(s) per user." % 1, command.user) command.delete(command) response['response'], response[ 'result'] = "error", "User limit encountered." return response # grab a URL in the format ^http://pastebin.com/raw.php?i=n1p4BU40 test = urlparse(command.url) # test if we have a good protocol and location - REFACTOR if not test.netloc: tweet_status( "I need a valid instance command which includes a ! before the command and a ^ before a valid URL.", user) response['response'], response[ 'result'] = "error", "Missing URL in instance command." return response # grab an instance to reserve instance = Instances() response = instance.reserve(command.url, bot.flavor_id) # notify the console message(response['result']['message'], response['response'], True) # return errors, if any if response['response'] == "error": return response # update the command to reflect the new instance status instance = response['result']['instance'] command.state = 10 command.updated = int(time.time()) command.instance_id = instance['id'] command.update() # pack command into response response['result']['command'] = command # tweet bits ask = "%0.6f" % (float(response['result']['ask']) / 1000000) address = response['result']['address'] name = instance['name'] # tell the user the bitcoin address tweet = "send %s BTC/hour to https://blockchain.info/address/%s in next 5 mins to start ~%s." % ( ask, address, name) tweet_status(tweet, command.user) return response
def get_stream(): # loop forever trying to talk to twitter while True: # load and check bot settings bot = TwitterBot.get() if not bot.enabled: sys.exit() # authenticate and begin try: auth = OAuth(bot.oauth_token, bot.oauth_token_secret, bot.consumer_key, bot.consumer_secret) # establish connection twitter_userstream = TwitterStream(auth=auth, domain='userstream.twitter.com') # iterator provides infinite status updates for update in twitter_userstream.user(): # look in the update for a text message (others include delete, friends) if 'text' in update: # skip it if it's a reply if update['in_reply_to_status_id']: continue # load the screen name/username user = update['user']['screen_name'] # check if somebody said 'settings' and then restart if "!settings" in update['text']: sys.exit() # grab the command in the format !instance r = re.search('\!([a-zA-Z]*)', update['text']) try: command = r.group(1) except: # always need a command continue # ignore ourselves if user == bot.screen_name: continue # ditch it if it's blank if command == "": continue # extract a url following a ^ try: r = re.search('\^(\S*)', update['text']) url = r.group(1) except: url = "" # grab an instance name in the format ~smi-avv4mtmm instance = None try: r = re.search('\~(\S*)', update['text']) # extract and lookup instance by name instance_name = r.group(1) instance = db.session.query(Instances).filter_by( name=instance_name).first() except: pass # write to database tc = TweetCommands() tc.created = int(time.time()) tc.updated = int(time.time()) tc.user = user tc.command = command.lower() tc.url = url if instance: tc.instance_id = instance.id else: tc.instance_id = 0 tc.state = 1 # initialize tc.update() # send message message("Received a command from Twitter", "success", False) app.logger.info("Received a command=(%s) from Twitter." % tc.command) else: # other types of messages pass except Exception as ex: app.logger.error( "Twitter stream disconnected. Letting monit handle restart.") time.sleep(15) return
def reserve_instance(command, bot): # default response response = {"response": "success", "result": {"message": ""}} # check quota if int(db.session.query(TweetCommands).filter_by(command="instance").count()) >= bot.max_instances: tweet_status("Sorry @%s, I'm at my %s instance quota. Wait a bit and try again." % (user, bot.max_instances)) command.delete(command) response["response"], response["result"] = "error", "Instance quota reached." return response # check the user doesn't have another instance already ic = db.session.query(TweetCommands).filter_by(command="instance", user=command.user).count() if ic > 1: tweet_status("Sorry, I only do %s instance(s) per user." % 1, command.user) command.delete(command) response["response"], response["result"] = "error", "User limit encountered." return response # grab a URL in the format ^http://pastebin.com/raw.php?i=n1p4BU40 test = urlparse(command.url) # test if we have a good protocol and location - REFACTOR if not test.netloc: tweet_status( "I need a valid instance command which includes a ! before the command and a ^ before a valid URL.", user ) response["response"], response["result"] = "error", "Missing URL in instance command." return response # grab an instance to reserve instance = Instances() response = instance.reserve(command.url, bot.flavor_id) # notify the console message(response["result"]["message"], response["response"], True) # return errors, if any if response["response"] == "error": return response # update the command to reflect the new instance status instance = response["result"]["instance"] command.state = 10 command.updated = int(time.time()) command.instance_id = instance["id"] command.update() # pack command into response response["result"]["command"] = command # tweet bits ask = "%0.6f" % (float(response["result"]["ask"]) / 1000000) address = response["result"]["address"] name = instance["name"] # tell the user the bitcoin address tweet = "send %s BTC/hour to https://blockchain.info/address/%s in next 5 mins to start ~%s." % (ask, address, name) tweet_status(tweet, command.user) return response
def get_stream(): # loop forever trying to talk to twitter while True: # load and check bot settings bot = TwitterBot.get() if not bot.enabled: sys.exit() # authenticate and begin try: auth = OAuth(bot.oauth_token, bot.oauth_token_secret, bot.consumer_key, bot.consumer_secret) # establish connection twitter_userstream = TwitterStream(auth=auth, domain="userstream.twitter.com") # iterator provides infinite status updates for update in twitter_userstream.user(): # look in the update for a text message (others include delete, friends) if "text" in update: # skip it if it's a reply if update["in_reply_to_status_id"]: continue # load the screen name/username user = update["user"]["screen_name"] # check if somebody said 'settings' and then restart if "!settings" in update["text"]: sys.exit() # grab the command in the format !instance r = re.search("\!([a-zA-Z]*)", update["text"]) try: command = r.group(1) except: # always need a command continue # ignore ourselves if user == bot.screen_name: continue # ditch it if it's blank if command == "": continue # extract a url following a ^ try: r = re.search("\^(\S*)", update["text"]) url = r.group(1) except: url = "" # grab an instance name in the format ~smi-avv4mtmm instance = None try: r = re.search("\~(\S*)", update["text"]) # extract and lookup instance by name instance_name = r.group(1) instance = db.session.query(Instances).filter_by(name=instance_name).first() except: pass # write to database tc = TweetCommands() tc.created = int(time.time()) tc.updated = int(time.time()) tc.user = user tc.command = command.lower() tc.url = url if instance: tc.instance_id = instance.id else: tc.instance_id = 0 tc.state = 1 # initialize tc.update() # send message message("Received a command from Twitter", "success", False) app.logger.info("Received a command=(%s) from Twitter." % tc.command) else: # other types of messages pass except Exception as ex: app.logger.error("Twitter stream disconnected. Letting monit handle restart.") time.sleep(15) return