예제 #1
0
	def post(self):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

		# load form values
		name = self.form.name.data.strip()
		description = self.form.description.data.strip()

		# check if we have it already
		if Cloud.get_by_user_name(user_info.key, name):
			self.add_message("A cloud with that name already exists!", "error")
			return self.redirect_to('account-clouds')

		# check what was returned from form validates
		if not self.form.validate():          
			self.add_message("The new cloud form did not validate.", "error")
			return self.get()

		cloud = Cloud(
			name = name,
			description = description,
			owner = user_info.key
		)
		cloud.put()

		# log to alert
		self.add_message("Cloud %s successfully created!" % name, "success")

		# give it a few seconds to update db, then redirect
		time.sleep(1)
		return self.redirect_to('account-clouds-configure', cloud_id = cloud.key.id())
예제 #2
0
    def post(self):
        # lookup user's auth info
        user_info = User.get_by_id(long(self.user_id))

        # load form values
        name = self.form.name.data.strip()
        description = self.form.description.data.strip()

        # check if we have it already
        if Cloud.get_by_user_name(user_info.key, name):
            self.add_message("A cloud with that name already exists!", "error")
            return self.redirect_to('account-clouds')

        # check what was returned from form validates
        if not self.form.validate():
            self.add_message("The new cloud form did not validate.", "error")
            return self.get()

        cloud = Cloud(name=name, description=description, owner=user_info.key)
        cloud.put()

        # log to alert
        self.add_message("Cloud %s successfully created!" % name, "success")

        # give it a few seconds to update db, then redirect
        time.sleep(1)
        return self.redirect_to('account-clouds-configure',
                                cloud_id=cloud.key.id())
예제 #3
0
	def get(self):
		# basics
		ip = self.request.remote_addr

		# setup channel to do page refresh
		channel_token = generate_token()
		refresh_channel = channel.create_channel(channel_token)

		# various pulldown initialization
		self.form.flavor.choices=[]
		self.form.wisp.choices=[]
		self.form.cloud.choices=[]

		# add list of user's flavors, if any
		flavors = Flavor.flavors_with_instances_on_sale()
		for flavor in flavors:
			self.form.flavor.choices.insert(0, (flavor.name, flavor.description))

		# used for determining element layout
		wisp = None
		cloud = None

		# if the user is logged in, we build out the list of their wisps
		if self.user_id:
			# lookup user's auth info and wisps
			user_info = User.get_by_id(long(self.user_id))
			wisps = Wisp.get_by_user(user_info.key)
			for wisp in wisps:
				self.form.wisp.choices.insert(0, (wisp.key.id(), wisp.name))
		
			# load clouds
			clouds = Cloud.get_by_user(user_info.key)

			# create default cloud if none
			if not clouds:
				cloud = Cloud.create_default(user_info.key)
				clouds.append(cloud)
				self.add_message("Default cloud created.", 'success')

			for cloud in clouds:
				self.form.cloud.choices.insert(0, (cloud.key.id(), cloud.name))

		# params build out (injects the last wisp, if there was one)
		params = {
			'remote_ip': ip,
			'wisp': wisp,
			'cloud': cloud,
			'refresh_channel': refresh_channel,
			'channel_token': channel_token 
		}

		return self.render_template('lab/launcher.html', **params)
예제 #4
0
	def delete(self, cloud_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# pull the entry from the db
		cloud = Cloud.get_by_id(long(cloud_id))

		# check the number of instances
		count = Instance.get_count_by_cloud(cloud.key)

		# deny if it has instances
		if count > 0:
			self.add_message('You may not delete a cloud with instances!', 'info')

		# if we found it and own it, delete
		elif cloud and cloud.owner == user_info.key:
			cloud.key.delete()
			self.add_message('Cloud successfully deleted!', 'success')
		else:
			self.add_message('Cloud was not deleted.  Something went horribly wrong somewhere!', 'warning')

		# hangout for a second
		time.sleep(1)

		# use the channel to tell the browser we are done and reload
		channel_token = self.request.get('channel_token')
		channel.send_message(channel_token, 'reload')
		return
예제 #5
0
	def post(self, cloud_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# load the cloud in question
		cloud = Cloud.get_by_id(long(cloud_id))
		
		# bail if cloud doesn't exist or not owned by this user
		if not cloud or cloud.owner != user_info.key:
			return self.redirect_to('account-clouds')
		
		# check what was returned from form validates
		if not self.form.validate():          
			self.add_message("The %s cloud was not updated." % cloud.name, "info")
			return self.redirect_to('account-clouds')

		# load form values
		name = self.form.name.data.strip()
		description = self.form.description.data.strip()

		# save the new cloud in our database            
		cloud.name = name
		cloud.description = description
		cloud.put()

		# log to alert
		self.add_message("Cloud %s updated!" % name, "success")

		# give it a few seconds to update db, then redirect
		time.sleep(1)
		
		return self.redirect_to('account-clouds')
예제 #6
0
	def get(self, cloud_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# get the cloud in question
		cloud = Cloud.get_by_id(long(cloud_id))

		# bail if cloud doesn't exist or not owned by this user
		if not cloud or cloud.owner != user_info.key:
			return self.redirect_to('account-clouds')

		# look up cloud's instances
		instances = Instance.get_by_cloud(cloud.key)

		# setup channel to do page refresh
		channel_token = user_info.key.urlsafe()
		refresh_channel = channel.create_channel(channel_token)

		# params build out
		params = {
			'cloud': cloud,
			'instances': instances, 
			'refresh_channel': refresh_channel,
			'channel_token': channel_token 
		}

		return self.render_template('cloud/edit.html', **params)
예제 #7
0
    def delete(self, cloud_id=None):
        # lookup user's auth info
        user_info = User.get_by_id(long(self.user_id))

        # pull the entry from the db
        cloud = Cloud.get_by_id(long(cloud_id))

        # check the number of instances
        count = Instance.get_count_by_cloud(cloud.key)

        # deny if it has instances
        if count > 0:
            self.add_message('You may not delete a cloud with instances!',
                             'info')

        # if we found it and own it, delete
        elif cloud and cloud.owner == user_info.key:
            cloud.key.delete()
            self.add_message('Cloud successfully deleted!', 'success')
        else:
            self.add_message(
                'Cloud was not deleted.  Something went horribly wrong somewhere!',
                'warning')

        # hangout for a second
        time.sleep(1)

        # use the channel to tell the browser we are done and reload
        channel_token = self.request.get('channel_token')
        channel.send_message(channel_token, 'reload')
        return
예제 #8
0
    def post(self, cloud_id=None):
        # lookup user's auth info
        user_info = User.get_by_id(long(self.user_id))

        # load the cloud in question
        cloud = Cloud.get_by_id(long(cloud_id))

        # bail if cloud doesn't exist or not owned by this user
        if not cloud or cloud.owner != user_info.key:
            return self.redirect_to('account-clouds')

        # check what was returned from form validates
        if not self.form.validate():
            self.add_message("The %s cloud was not updated." % cloud.name,
                             "info")
            return self.redirect_to('account-clouds')

        # load form values
        name = self.form.name.data.strip()
        description = self.form.description.data.strip()

        # save the new cloud in our database
        cloud.name = name
        cloud.description = description
        cloud.put()

        # log to alert
        self.add_message("Cloud %s updated!" % name, "success")

        # give it a few seconds to update db, then redirect
        time.sleep(1)

        return self.redirect_to('account-clouds')
예제 #9
0
    def get(self, cloud_id=None):
        # lookup user's auth info
        user_info = User.get_by_id(long(self.user_id))

        # get the cloud in question
        cloud = Cloud.get_by_id(long(cloud_id))

        # bail if cloud doesn't exist or not owned by this user
        if not cloud or cloud.owner != user_info.key:
            return self.redirect_to('account-clouds')

        # look up cloud's instances
        instances = Instance.get_by_cloud(cloud.key)

        # setup channel to do page refresh
        channel_token = user_info.key.urlsafe()
        refresh_channel = channel.create_channel(channel_token)

        # params build out
        params = {
            'cloud': cloud,
            'instances': instances,
            'refresh_channel': refresh_channel,
            'channel_token': channel_token
        }

        return self.render_template('cloud/edit.html', **params)
예제 #10
0
	def get(self):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

		# look up appliances
		clouds = Cloud.get_by_user(user_info.key)

		# setup channel to do page refresh
		channel_token = user_info.key.urlsafe()
		refresh_channel = channel.create_channel(channel_token)

		# params build out
		params = {
			'clouds': clouds, 
			'refresh_channel': refresh_channel,
			'channel_token': channel_token 
		}

		return self.render_template('cloud/clouds.html', **params)
예제 #11
0
    def get(self):
        # lookup user's auth info
        user_info = User.get_by_id(long(self.user_id))

        # look up appliances
        clouds = Cloud.get_by_user(user_info.key)

        # setup channel to do page refresh
        channel_token = user_info.key.urlsafe()
        refresh_channel = channel.create_channel(channel_token)

        # params build out
        params = {
            'clouds': clouds,
            'refresh_channel': refresh_channel,
            'channel_token': channel_token
        }

        return self.render_template('cloud/clouds.html', **params)
예제 #12
0
	def post(self):
		# request basics
		ip = self.request.remote_addr

		# response, type, cross posting
		params = {}
		self.response.headers['Content-Type'] = "application/json"
		self.response.headers['Access-Control-Allow-Origin'] = '*'

		# check if this IP has any other bids open
		instancebid = InstanceBid.get_incomplete_by_ip(ip)


		# check we have an instancebid already
		if instancebid:
			# validate wisp
			if instancebid.wisp == None:
				instancebid.key.delete()
				return error_response(self, "Deleting bid because no wisp was associated.", 403, params)

			# load the payment address
			if instancebid.instance:
				instancebid.address = instancebid.instance.get().address
				instancebid.ask = instancebid.instance.get().ask
			else:
				# we should have an instance assosciated, so bail on this one
				instancebid.key.delete()
				return error_response(self, "Deleting bid because no instance was associated.", 403, params)

			params['response'] = "error"
			params['message'] = "The calling IP address already has an instance reservation in progress."
			params['instancebid'] = instancebid
			self.response.set_status(403)
			return self.render_template('api/bid.json', **params)	

		# load POSTed JSON
		try:
			request = json.loads(self.request.body)
		except Exception as ex:
			return error_response(self, "Failure in parsing request JSON.", 403, params)

		# load optional values or defaults
		# ipv4 (allow default)
		if 'requires_ipv4' in request:
			requires_ipv4 = request['requires_ipv4']
		else:
			requires_ipv4 = 0
		
		# ipv6 (allow default)
		if 'requires_ipv6' in request:
			requires_ipv6 = request['requires_ipv6']
		else:
			requires_ipv6 = 0

		# providers (allow default)
		if 'providers' in request:
			providers = request['providers']
		else:
			providers = [{u'id': 1, u'name': u'All Providers'}]		

		# flavors (required)
		if 'flavor' in request:
			flavor_name = request['flavor']
			flavor = Flavor.get_by_name(flavor_name)

			# check if flavor was found
			if not flavor:
				return error_response(self, "Flavor not found.", 403, params)

		else:
			return error_response(self, "Flavor name is required.", 403, params)

		# cloud (optional)
		if 'cloud_id' in request:
			cloud_id = request['cloud_id']
			cloud = Cloud.get_by_id(long(cloud_id))

			# check if cloud was found
			if not cloud:
				return error_response(self, "Cloud ID not found.", 403, params)
		else:
			cloud = None

		# disallow both a wisp and a callback_url
		if 'wisp_id' in request and 'callback_url' in request:
			return error_response(self, "A wisp and a callback URL may not be used together.", 403, params)

		# require either a wisp or a callback_url
		if 'wisp_id' not in request and 'callback_url' not in request:
			return error_response(self, "A valid wisp or a callback URL is required.", 403, params)

		# load the wisp, if there is one
		if 'wisp_id' in request:
			wisp_id = request['wisp_id']
			wisp = Wisp.get_by_id(long(wisp_id))
		else:
			wisp = None
		
		# load the callback URL, if there is one
		if 'callback_url' in request:
			callback_url = request['callback_url']
		elif wisp:
			callback_url = wisp.callback_url
		else:
			callback_url = ""

		# test we have a callback_url or a valid image in the wisp
		if callback_url > "":
			try:
				result = urlfetch.fetch(callback_url, deadline=5)
				if result.status_code > 399:
					return error_response(self, "The callback URL is unreachable.", 403, params)
				# test result's image URL
			except Exception as ex:
				return error_response(self, "The callback URL is unreachable.", 403, params)
		elif wisp:
			if wisp.image == None and wisp.dynamic_image_url == None and wisp.project == None:
				return error_response(self, "A valid wisp or a callback URL is required.", 403, params)

		# grab a new bid hash to use for the new bid
		token = generate_token(size=16)
		name = "smr-%s" % generate_token(size=8)

		# create a new bid
		instancebid = InstanceBid()
		instancebid.token = token
		instancebid.name = name
		instancebid.need_ipv4_address = bool(requires_ipv4)
		instancebid.need_ipv6_address = bool(requires_ipv6)
		instancebid.flavor = flavor.key
		instancebid.remote_ip = ip
		instancebid.appliances = providers # providers is already JSON
		instancebid.status = 0
		instancebid.callback_url = callback_url

		# expires in 5 minutes
		epoch_time = int(time.time())
		instancebid.expires = datetime.fromtimestamp(epoch_time+300)

		# add wisp, if present
		if wisp:
			instancebid.wisp = wisp.key
		
		# add cloud, if present
		if cloud:
			instancebid.cloud = cloud.key

		# update
		instancebid.put()

		# sleep for dev
		if config.debug:
			time.sleep(2)

		# reserve the instance
		InstanceBid.reserve_instance_by_token(instancebid.token)

		# get the address, if you got an instance
		if instancebid.instance:
			address = instancebid.instance.get().address
			ask = instancebid.instance.get().ask
		else:
			# no instance was reserved
			instancebid.key.delete()
			return error_response(self, "No valid instances were returned.", 403, params)
			
		# hack address and ask into instancebid object for template (not stored)
		instancebid.address = address
		instancebid.ask = ask

		# build out the response
		params['response'] = "success"
		params['message'] = "A new instance bid has been created."	
		params['instancebid'] = instancebid

		# return response and include cross site POST headers
		self.response.set_status(201)

		return self.render_template('api/bid.json', **params)