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')
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
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)
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
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')
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)
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)