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

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

		# check for url param or referer
		url = ""
		if 'url' in self.request.GET:
			url = urllib2.unquote(self.request.GET['url'])

		# if we have a URL, we deal with it
		if url:
			project = Project.get_by_url(url)
			if not project:
				# create a new project for this user
				self.form.url.data = url
				return self.post()
			else:
				# go to the existing project
				return self.redirect_to('account-projects-detail', project_id = project.key.id())

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

		return self.render_template('project/new.html', **params)
Example #2
0
	def delete(self, project_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# pull the entry from the db
		project = Project.get_by_id(long(project_id))

		# if we found it and own it
		if project and project.owner == user_info.key:
			# patch all wisps using project to stock
			Wisp.patch_to_stock(project.key)

			# delete the project
			project.key.delete()

			self.add_message('Project successfully deleted!', 'success')
		else:
			self.add_message('Project 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
	def get(self):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

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

		# load projects pulldown
		self.form.project.choices = []

		# public + private
		projects = Project.get_available(user_info.key)
		for project in projects:
			self.form.project.choices.insert(0, (str(project.key.id()), project.name))

		# insert images into list for wisp
		self.form.image.choices=[('custom', "Dynamic Image URL")]
		images = Image.get_all()
		for image in images:
			self.form.image.choices.insert(0, (str(image.key.id()), image.description))

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

		return self.render_template('wisp/new.html', **params)
Example #4
0
	def get(self):
		# check for referer (only works SSL to SSL site) or parameter in URL (for custom page)
		url = ""
		if 'url' in self.request.GET:
			url = urllib2.unquote(self.request.GET['url'])
		elif self.request.referer:
			if config.github_url in self.request.referer:
				url = urllib2.unquote(self.request.referer)

		# lowercase url and strip slashes
		url = url.lower().strip('/')

		# run regex to get base URL
		match = re.search('https://github.com/([\w]*)/([\w]*)', url)
		if match:
			# pull out the match
			url = match.group()

			# if we have a URL, we look it up
			if url:
				project = Project.get_by_url(url)

				if project:
					# go to the existing project
					return self.redirect_to('account-projects-view', project_id = project.key.id())
				else:
					# if user is logged in, redirect to the new page
					if self.user_id:
						params = {'url': url}
						return self.redirect_to('account-projects-new', **params)

		# load all public projects
		projects = Project.get_public()

		# params build out
		params = {
			'projects': projects
		}

		return self.render_template('site/projects.html', **params)
Example #5
0
	def get(self, token = None):
		# lookup up bid
		bid = InstanceBid.get_by_token(token)
		if not bid:
			self.add_message("Instance reservation token %s has expired." % token, 'error')
			return self.redirect_to('projects')

		# grab the project from the bid
		project = Project.get_by_id(bid.wisp.get().project.id())

		# grab the instance
		instance = Instance.get_by_token(token)
		if not instance:
			self.add_message("All available instance reservations are in use. Please try again in a few minutes.", 'error')
			return self.redirect_to('projects')

		# grab and render the README.md file
		content = urlfetch.fetch('http://10.0.1.80:8079/wisps/6048757061779456/README.md').content

		readme_html = bleach.clean(
			markdown.markdown(
				unicode(content, 'utf-8')
			), 
			config.bleach_tags,
			config.bleach_attributes
		)	

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

		params = {
			'instance': instance,
			'bid': bid,
			'project': project,
			'readme_html': readme_html,
			'refresh_channel': refresh_channel,
			'channel_token': channel_token 
		}
		return self.render_template('project/bid.html', **params)
Example #6
0
	def get(self, project_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

		# get the project in question
		project = Project.get_by_id(long(project_id))

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

		# load form values
		self.form.name.data = project.name
		self.form.description.data = project.description
		self.form.address.data = project.address
		self.form.amount.data = project.amount
		self.form.vpus.data = project.vpus
		self.form.memory.data = project.memory
		self.form.disk.data = project.disk
		self.form.port.data = project.port
		self.form.dynamic_image_url.data = project.dynamic_image_url

		# insert images into list
		self.form.image.choices=[('custom', "Dynamic Image URL")]
		images = Image.get_all()
		for image in images:
			self.form.image.choices.insert(0, (str(image.key.id()), image.description))

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

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

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

		# look up projects
		projects = Project.get_by_user(user_info.key)

		# redirect if we don't have any projects
		if not projects:
			return self.redirect_to('account-projects-new')

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

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

		return self.render_template('project/list.html', **params)
Example #8
0
	def get(self, project_id = None, action = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# load the project in question
		project = Project.get_by_id(long(project_id))

		# deny if not owner
		if project.owner != user_info.key:
			return

		# refresh
		if action == 'refresh':
			# sync if project exists and the user is owner
			if project and project.owner == user_info.key:
				response = project.sync()
				time.sleep(1)

			# log to alert
			if response['response'] == "success":
				self.add_message("Project %s successfully synced!" % project.name, "success")
			else:
				self.add_message("%s" % response['result']['message'], "fail")

		# publish status
		if action == 'private':
			project.public = False
			project.put()
		if action == 'public':
			project.public = True
			project.put()

		# 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
Example #9
0
	def post(self):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

		# check what was returned from form validates     
		if not self.form.validate():
			for key, value in self.form.errors.iteritems():
				self.add_message("Fix the %s. %s" % (key, value[0]), "error")
			return self.get()

		# load form values
		url = self.form.url.data.strip()
		
		# check if we have it already
		if Project.get_by_url(url):
			self.add_message("A project with that URL already exists.", "error")
			return self.redirect_to('account-projects')		

		# get the basic repo data
		response = github.repo_base(url)
		if response['response'] == 'success':
			repo = response['result']['repo']
		else:
			repo = None
			self.add_message(response['result']['message'], 'error')
			return self.redirect_to('projects')

		# save the new project in our database
		project = Project()           
		project.url = url.lower().strip('/')
		project.name = repo['name'] # this one is editable later
		project.repo_name = repo['name'] # this one is not
		project.address = None
		project.amount = 0
		project.description = repo['description']
		project.owner = user_info.key
		project.public = False
		project.port = 80
		project.put()

		# give it a second
		time.sleep(1)

		# check if the repo has the utterio directory
		response = project.sync()

		# log to alert
		if response['response'] == "success":
			self.add_message("Project %s successfully added!" % project.name, "success")
		else:
			self.add_message("%s" % response['result']['message'], "fail")

		# redirect
		return self.redirect_to('account-projects-detail', project_id = project.key.id())
Example #10
0
	def get(self, project_id = None):
		project = Project.get_by_id(long(project_id))
		# if no project
		if not project:
			return self.redirect_to('projects')

		# assume this user is not owner
		owner = False

		# print self.render_url(project.json_url, {})

		# determine if we can show the project
		if not project.public:
			# see if we have a user
			try:
				user_info = User.get_by_id(long(self.user_id))
				if user_info.key != project.owner:
					raise Exception
				else:
					owner = True

			except:
				self.add_message("You must be the owner to do this.", "fail")
				return self.redirect_to('projects')
		else:
			try:
				user_info = User.get_by_id(long(self.user_id))
				if user_info.key == project.owner:
					owner = True

			except:
				user_info = None

		# define minimum specifications for the instance
		specs = {
			'vpus': project.vpus,
			'memory': project.memory,
			'disk': project.disk
		}

		# empty forms
		self.form.provider.choices = []
		self.form.flavor.choices = []

		# plenty?
		plenty = False

		# dict of providers
		providers = {}

		# find the all public provider's appliances and add to providers object
		appliances = Appliance.get_by_group(None)
		for appliance in appliances:
			providers[appliance.key.id()] = {
				'name': "%s (Public)" % appliance.name,
				'location': [appliance.location.lat, appliance.location.lon],
				'flavors': []
			}

		# if there is a user, find his groups and do the same with appliances in those groups
		if user_info:
			groups = Group.get_by_owner(user_info.key)
			for group in groups:
				appliances = Appliance.get_by_group(group.key)
				for appliance in appliances:
					providers[str(appliance.key.id())] = {
						'name': "%s of %s (Hybrid Group)" % (appliance.name, group.name),
						'location': [appliance.location.lat, appliance.location.lon],
						'flavors': []
					}

		# iterate over the dictionary of providers
		for provider in providers:
			# find the list of flavors for this provider which support this project
			flavors = Flavor.flavors_with_min_specs_by_appliance_on_sale(
				specs, 
				ndb.Key('Appliance', long(provider))
			)

			# add provider to the form and the flavors to provider object if flavors exist
			if flavors:
				plenty = True
				# insert this provider's appliance into the form
				self.form.provider.choices.insert(0, (provider, providers[provider]['name']))

				# insert flavors into object
				for flavor in flavors:
					providers[provider]['flavors'].append(
						{
							'id': str(flavor.key.id()),
							'name': flavor.name,
							'description': flavor.description
						}
					)

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

		# params build out
		params = {
			'project': project,
			'providers': json.dumps(providers),
			'plenty': plenty,
			'owner': owner,
			'refresh_channel': refresh_channel,
			'channel_token': channel_token 
		}

		return self.render_template('project/view.html', **params)
Example #11
0
	def post(self, project_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# load the project in question
		project = Project.get_by_id(long(project_id))
		
		# bail if project doesn't exist or not owned by this user
		if not project or project.owner != user_info.key:
			return self.redirect_to('account-projects')

		# insert images into list for wisp
		self.form.image.choices=[('custom', "Dynamic Image URL")]
		images = Image.get_all()
		for image in images:
			self.form.image.choices.insert(0, (str(image.key.id()), image.description))

		# check what was returned from form validates
		if not self.form.validate():
			for key, value in self.form.errors.iteritems():
				self.add_message("Fix the %s. %s." % (key, value[0].strip('. ')), "error")

		# stuff to set that might have errors
		if not self.form.name.errors:
			name = self.form.name.data.strip()
			project.name = name
		if not self.form.description.errors:
			description = self.form.description.data.strip()
			project.description = description
		if not self.form.address.errors:
			address = self.form.address.data.strip()
			project.address = address
		if not self.form.amount.errors:
			amount = self.form.amount.data
			project.amount = int(amount)
		if not self.form.dynamic_image_url.errors:
			dynamic_image_url = self.form.dynamic_image_url.data.strip()
			project.dynamic_image_url = dynamic_image_url

		# handle a custom image setting
		if self.form.image.data.strip() == "custom":
			image = None
		else:
			image = Image.get_by_id(int(self.form.image.data.strip())).key
		project.image = image

		# pulldowns (no errors)
		vpus = self.form.vpus.data
		project.vpus = int(vpus)
		memory = self.form.memory.data
		project.memory = int(memory)
		disk = self.form.disk.data
		project.disk = int(disk)
		image = self.form.image.data
		port = self.form.port.data

		# save the new project in our database
		project.put()

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

		# give it a few seconds to update db, then redirect
		time.sleep(1)
		
		return self.get(project_id = project.key.id())
Example #12
0
	def post(self):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

		# load projects pulldown
		self.form.project.choices = []

		# public + private
		projects = Project.get_available(user_info.key)
		for project in projects:
			self.form.project.choices.insert(0, (str(project.key.id()), project.name))

		# insert images into list for wisp
		self.form.image.choices=[('custom', "Dynamic Image URL")]
		images = Image.get_all()
		for image in images:
			self.form.image.choices.insert(0, (str(image.key.id()), image.description))

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

		# load form values
		name = self.form.name.data.strip()
		ssh_key = self.form.ssh_key.data.strip()
		dynamic_image_url = self.form.dynamic_image_url.data.strip()
		image_container_format = self.form.image_container_format.data.strip()
		image_disk_format = self.form.image_disk_format.data.strip()
		post_creation = self.form.post_creation.data.strip()
		callback_url = self.form.callback_url.data.strip()
		default = self.form.default.data # no strip cause bool

		# check if project is selected
		if self.form.wisp_type.data.strip() == 'project':
			project = Project.get_by_id(long(self.form.project.data.strip())).key
		else:
			project = None		

		# hack up form to deal with custom image
		if self.form.image.data.strip() == "custom":
			image = None
		else:
			image = Image.get_by_id(long(self.form.image.data.strip())).key

		# hack up form to deal with custom callback
		if self.form.wisp_type.data.strip() == "custom":
			image = None
			ssh_key = None
			dynamic_image_url = None
			post_creation = None
		elif self.form.wisp_type.data.strip() == "project":
			image = None
			dynamic_image_url = None
			post_creation = None
		else:
			callback_url = None

		# check if we have it already
		if Wisp.get_by_user_name(user_info.key, name):
			self.add_message("A wisp with that name already exists in this account!", "error")
			return self.redirect_to('account-wisps')		
		
		# check if we need to force default setting for first new wisp
		if not Wisp.get_by_user(user_info.key):
			default = True

		# save the new wisp in our database            
		wisp = Wisp(
			name = name,
			owner = user_info.key,
			image = image,
			ssh_key = ssh_key,
			dynamic_image_url = dynamic_image_url,
			image_container_format = image_container_format,
			image_disk_format = image_disk_format,
			post_creation = post_creation,
			callback_url = callback_url,
			project = project
		)
		wisp.put()

		# set default if true
		if default:
			Wisp.set_default(wisp)

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

		# give it a few seconds to update db, then redirect
		time.sleep(1)
		return self.redirect_to('account-wisps-detail', wisp_id=wisp.key.id())
Example #13
0
	def post(self, wisp_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))

		# load the wisp in question
		wisp = Wisp.get_by_id(long(wisp_id))

		# if doesn't exist, redirect
		if not wisp:
			return self.redirect_to('account-wisps')

		# load projects pulldown
		self.form.project.choices = []
		projects = Project.get_available(user_info.key)
		for project in projects:
			self.form.project.choices.insert(0, (str(project.key.id()), project.name))

		# insert images into list for wisp
		self.form.image.choices=[('custom', "Dynamic Image URL")]
		images = Image.get_all()
		for image in images:
			self.form.image.choices.insert(0, (str(image.key.id()), image.description))

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

		# load form values
		name = self.form.name.data.strip()
		ssh_key = self.form.ssh_key.data.strip()
		dynamic_image_url = self.form.dynamic_image_url.data.strip()
		image_container_format = self.form.image_container_format.data.strip()
		image_disk_format = self.form.image_disk_format.data.strip()
		post_creation = self.form.post_creation.data.strip()
		callback_url = self.form.callback_url.data.strip()
		default = self.form.default.data

		# hack up form to deal with custom callback
		if self.form.wisp_type.data.strip() == "custom":
			# custom callback, so zero everything
			image = None
			ssh_key = None
			dynamic_image_url = None
			post_creation = None
			project = None
		elif self.form.wisp_type.data.strip() == "project":
			# project, so zero image, urls, post_creation
			image = None
			dynamic_image_url = None
			post_creation = None
			callback_url = None
			project = Project.get_by_id(long(self.form.project.data.strip())).key
		else:
			# stock
			callback_url = None
			project = None

		# hack up results to deal with custom images
		if self.form.image.data.strip() == "custom":
			image = None
		else:
			if project:
				image = None
			else:
				image = Image.get_by_id(int(self.form.image.data.strip())).key


		# check if the wisp owner is this user
		if wisp and wisp.owner == user_info.key:
			# save the new wisp in our database            
			wisp.name = name
			wisp.image = image
			wisp.ssh_key = ssh_key
			wisp.dynamic_image_url = dynamic_image_url
			wisp.image_container_format = image_container_format
			wisp.image_disk_format = image_disk_format
			wisp.post_creation = post_creation
			wisp.callback_url = callback_url
			wisp.project = project
			wisp.put()

			# set default if true, or turn it off if false
			if default:
				Wisp.set_default(wisp)
			else:
				wisp.default = False
				wisp.put()

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

			# give it a few seconds to update db, then redirect
			time.sleep(1)
		else:
			# log to alert
			self.add_message("Wisp was not updated!", "error")
		
		return self.redirect_to('account-wisps')
Example #14
0
	def get(self, wisp_id = None):
		# lookup user's auth info
		user_info = User.get_by_id(long(self.user_id))
		
		# get the wisp in question
		wisp = Wisp.get_by_id(long(wisp_id))

		# if doesn't exist, redirect
		if not wisp:
			return self.redirect_to('account-wisps')

		# load projects pulldown
		self.form.project.choices = []
		projects = Project.get_available(user_info.key)
		for project in projects:
			self.form.project.choices.insert(0, (str(project.key.id()), project.name))

		# insert images into list for wisp
		self.form.image.choices=[('custom', "Dynamic Image URL")]
		images = Image.get_all()
		for image in images:
			self.form.image.choices.insert(0, (str(image.key.id()), image.description))

		# load values out of db to show in form
		self.form.name.data = wisp.name
		self.form.ssh_key.data = wisp.ssh_key
		self.form.dynamic_image_url.data = wisp.dynamic_image_url
		self.form.image_disk_format.data = wisp.image_disk_format
		self.form.image_container_format.data = wisp.image_container_format
		self.form.post_creation.data = wisp.post_creation
		self.form.callback_url.data = wisp.callback_url
		self.form.default.data = wisp.default

		# adjust the form's pulldown settings
		self.form.wisp_type.data = "stock"
		if wisp.image:
			self.form.image.data = str(wisp.image.id())
		if wisp.callback_url:
			self.form.wisp_type.data = "custom"
		if wisp.project:
			self.form.wisp_type.data = "project"
			self.form.project.data = str(wisp.project.id())
		if wisp.dynamic_image_url:
			self.form.wisp_type.data = "stock"
			self.form.image.data = "custom"

		# check if the owner is this user
		if wisp and wisp.owner == 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 = {
				'wisp': wisp,
				'refresh_channel': refresh_channel,
				'channel_token': channel_token 
			}

			return self.render_template('wisp/edit.html', **params)
		
		else:
			return self.redirect_to('account-wisps')
Example #15
0
	def post(self):
		# try to pull get user info from a browser based session
		if self.user_id:
			user_info = User.get_by_id(long(self.user_id))
		else:
			user_info = None

		# paramters, assume failure, response type
		params = {}
		params['response'] = "error"
		self.response.headers['Content-Type'] = "application/json"

		# response headers
		self.response.headers['Content-Type'] = "application/json"
		self.response.headers['Access-Control-Allow-Origin'] = '*'

		# load various variables
		body = json.loads(self.request.body)
		
		# SSH key (not required)
		try:
			ssh_key = body['ssh_key']
		except:
			ssh_key = ""

		# load project if we have it
		try:
			project_id = body['project_id']
			project = Project.get_by_id(long(project_id))
		except:
			project = None

		# handle project wisps differently
		if project:
			wisp = Wisp().from_project(
				ssh_key,
				project,
				user_info
			)
		else:
			try:
				post_creation = body['post_creation']
			except:
				post_creation = ""

			try:
				image_id = body['image_id']
				image = Image.get_by_id(long(image_id))
			except:
				try:
					dynamic_image_url = body['dynamic_image_url']
				except:
					# we don't have an image or a URL, so nothing can do
					params['message'] = "Wisps require an image to boot."
					self.response.set_status(401)
					return self.render_template('api/response.json', **params)

			# disk and container formats if they were sent (usually qcow/bare)
			try:
				image_disk_format = body['image_disk_format']
			except:
				image_disk_format = "qcow2"
			try:
				image_container_format = body['image_container_format']
			except:
				image_container_format = "bare"

			# create an anonymous wisp if we don't have it already
			wisp = Wisp().from_stock(
				ssh_key, 
				post_creation, 
				dynamic_image_url, 
				image_disk_format, 
				image_container_format,
				user_info
			)

		if wisp:	
			# return JSON response
			params['response'] = "success"
			params['wisp'] = wisp
			
			return self.render_template('api/wisp.json', **params)
		else:
			params['message'] = "Wisp creation failed."
			self.response.set_status(401)
			return self.render_template('api/response.json', **params)