def configure_flavors_detail(flavor_id): # get the matching flavor flavor = db.session.query(Flavors).filter_by(id=flavor_id).first() # handle a GET if request.method == 'GET': # check configuration settings = Status().check_settings() # how much is a micro BTC? try: quote = float( coinbase_get_quote( currency='btc_to_usd')['result']['btc_to_usd']) / 1000000 except: quote = 0 return render_template('/configure/flavor_detail.html', settings=settings, quote=quote, flavor=flavor) # handle a PUT elif request.method == 'PUT': # clear settings cache Status().flush() try: state = int(request.form['enable']) flavor.active = state # set instances with this flavor to the state instances = Instances() instances.toggle(flavor.id, state) except: pass try: ask = request.form['ask'] flavor.ask = ask except: pass # update entry flavor.update() return jsonify({"response": "success", "flavor": row2dict(flavor)})
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 configure_flavors_detail(flavor_id): # get the matching flavor flavor = db.session.query(Flavors).filter_by(id=flavor_id).first() # clear settings cache Status().flush() # enable/diskable if 'enable' in request.form.keys(): flavor.update(active=int(request.form['enable'])) # set ask if 'ask' in request.form.keys(): flavor.update(ask=int(request.form['ask'])) # set max-instances if 'max-instances' in request.form.keys(): flavor.update(max_instances=int(request.form['max-instances'])) # install pool flavor if 'install' in request.form.keys(): # let's see what we can break, er install try: if not flavor: response = jsonify({ "response": "error", "result": { "message": "Flavor %s not found." % flavor_id } }) response.status_code = 404 return response # we are told to install if int(request.form['install']): response = flavor_verify_install(flavor) if not response['response'] == 'success': raise Exception(response['result']['message']) if flavor.ask > 0: flavor.update(active=True) else: flavor.update(active=False) else: # we are told to uninstall (install=0) response = flavor_uninstall(flavor) if not response['response'] == 'success': raise Exception(response['result']['message']) flavor.update(installed=False, active=False, osid=None) except Exception as e: response = jsonify({ "response": "error", "result": { "message": str(e) } }) response.status_code = 403 return response # set instance state to match flavor's state instances = Instances() instances.toggle(flavor.id, flavor.active) # update the ask prices on the openstack cluster using metadata try: # get current ask price on openstack and update flavor.save() # warn because we couldn't update the ask price that's set on openstack except nova_exceptions.Forbidden: app.logger.warning( 'No permissions to update price of flavor "{0}".'.format( flavor.name)) return response # handle any other exception while talking to openstack except Exception as e: app.logger.warning('Error updating price of flavor "{0}": {1}.'.format( flavor.name, str(e))) return jsonify({"response": "success", "flavor": row2dict(flavor)})