예제 #1
0
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)})
예제 #2
0
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
예제 #3
0
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)})
예제 #4
0
	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)
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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)})
예제 #8
0
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
예제 #9
0
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)})