def post(self): if not self.form.validate(): self.add_message("The form did not validate.", 'error') return self.get() # load values out of the form name = self.form.name.data.strip() vpus = self.form.vpus.data memory = self.form.memory.data disk = self.form.disk.data network_down = self.form.network_down.data network_up = self.form.network_up.data rate = self.form.rate.data # save the flavor in our database flavor = Flavor( name = name, vpus = vpus, memory = memory, disk = disk, network_down = network_down, network_up = network_up, rate = rate, # current market rate launches = 0, # number of total launches hot = 2 # suggest minimum two instance addresses hot ) flavor.put() # log to alert self.add_message(('Flavor %s successfully created!' % name), 'success') # give it a few seconds to update db, then redirect time.sleep(1) return self.redirect_to('admin-flavors')
def post(self): if not self.form.validate(): self.add_message("The form did not validate.", 'error') return self.get() # load values out of the form name = self.form.name.data.strip() description = self.form.description.data.strip() vpus = self.form.vpus.data memory = self.form.memory.data disk = self.form.disk.data network = self.form.network.data rate = self.form.rate.data # save the flavor in our database flavor = Flavor( name=name, description=description, vpus=vpus, memory=memory, disk=disk, network=network, rate=rate, # current market rate launches=0, # number of total launches hot=2 # suggest minimum two instance addresses hot ) flavor.put() # log to alert self.add_message(('Flavor %s successfully created!' % name), 'success') # give it a few seconds to update db, then redirect time.sleep(1) return self.redirect_to('admin-flavors')
def post(self, action): self.response.headers['Content-Type'] = 'application/json' self.response.set_status(200) # write dictionary as json string self.response.out.write(json.dumps( # retrieve flavors as schema and convert schema to dict Flavor.as_schema_list( # pass get_all method as query object Flavor.query()).as_dict()))
def post(self): # get current flavors flavors = Flavor().get_all() # build parameter list params = { 'flavors': flavors } # return images via template self.response.headers['Content-Type'] = 'application/json' return self.render_template('api/flavors.json', **params)
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)
def get(self): # lookup user's auth info user_info = User.get_by_id(long(self.user_id)) # look up user's articles flavors = Flavor.get_all() # setup channel to do page refresh channel_token = user_info.key.urlsafe() refresh_channel = channel.create_channel(channel_token) params = { 'flavors': flavors, 'refresh_channel': refresh_channel, 'channel_token': channel_token } return self.render_template('admin/flavors.html', **params)
def delete(self, flavor_id = None): # delete the entry from the db flavor = Flavor.get_by_id(long(flavor_id)) if flavor: flavor.key.delete() self.add_message('Flavor successfully deleted!', 'success') else: self.add_message('Flavor 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 put(self, flavor_id=None): flavor = Flavor.get_by_id(long(flavor_id)) # get the enable/active state enable = self.request.get("enable") if flavor: if enable == '1': flavor.active = True flavor.put() else: flavor.active = False flavor.put() # hangout for a second time.sleep(1) return
def put(self, flavor_id = None): flavor = Flavor.get_by_id(long(flavor_id)) # get the enable/active state enable = self.request.get("enable") if flavor: if enable == '1': flavor.active = True flavor.put() else: flavor.active = False flavor.put() # hangout for a second time.sleep(1) return
def delete(self, flavor_id=None): # delete the entry from the db flavor = Flavor.get_by_id(long(flavor_id)) if flavor: flavor.key.delete() self.add_message('Flavor successfully deleted!', 'success') else: self.add_message( 'Flavor 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 prepare_flavor(self, flavor_specs): flavor = Flavor.get_by_merge(**flavor_specs) return [ ('flavor', flavor.key), ('ask', flavor_specs['ask']),]
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)
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)