def delete(self, instance_id: uuid.UUID): cherrypy.response.status = 204 # Fix for https://github.com/cherrypy/cherrypy/issues/1657 del cherrypy.response.headers['Content-Type'] with cherrypy.request.db_session() as session: instance: Instance = session.merge( cherrypy.request.resource_object, load=False) if instance.state not in [ InstanceState.STOPPED, InstanceState.ACTIVE, InstanceState.ERROR ]: raise cherrypy.HTTPError( 409, "Can only delete an instance in the following states: %s" % [ InstanceState.STOPPED.value, InstanceState.ACTIVE.value, InstanceState.ERROR.value ]) instance.state = InstanceState.DELETING create_task(session, instance, delete_instance, instance_id=instance.id, delete_backing=True) session.commit()
def action_start(self, instance_id: uuid.UUID): cherrypy.response.status = 202 with cherrypy.request.db_session() as session: instance: Instance = session.merge( cherrypy.request.resource_object, load=False) if instance.state != InstanceState.STOPPED: raise cherrypy.HTTPError( 400, "Can only start an instance in the following state: %s" % InstanceState.STOPPED.value) if instance.state != InstanceState.STOPPED: raise cherrypy.HTTPError( 409, "Can only start an instance in the following state: %s" % InstanceState.STOPPED.value) instance.state = InstanceState.STARTING create_task(session, instance, start_instance, instance_id=instance.id) session.commit()
def delete(self, image_id): cherrypy.response.status = 204 # Fix for https://github.com/cherrypy/cherrypy/issues/1657 del cherrypy.response.headers['Content-Type'] with cherrypy.request.db_session() as session: image: Image = session.merge(cherrypy.request.resource_object, load=False) if image.state not in [ImageState.CREATED, ImageState.ERROR]: raise cherrypy.HTTPError( 409, "Can only delete an image while it is in the following states: %s" % ([ImageState.CREATED.value, ImageState.ERROR.value])) if image.locked: raise cherrypy.HTTPError( 409, "Cannot delete an image while it is locked.") image.state = ImageState.DELETING # TODO: do we allow not deleting image backing? create_task(session, image, delete_image, image_id=image.id, delete_backing=True) session.commit()
def create(self): request: RequestCreateRegion = cherrypy.request.model with cherrypy.request.db_session() as session: region = session.query(Region).filter( Region.name == request.name).first() if region is not None: raise cherrypy.HTTPError( 409, 'A region with the requested name already exists.') region = Region() region.name = request.name region.datacenter = request.datacenter region.image_datastore = request.image_datastore region.schedulable = False if request.image_folder is not None: region.image_folder = request.image_folder session.add(region) session.flush() create_task(session, region, create_region, region_id=region.id) session.commit() session.refresh(region) return ResponseRegion.from_database(region)
def create(self): request: RequestCreateImage = cherrypy.request.model if request.visibility == ImageVisibility.PUBLIC: self.mount.enforce_policy("images:create:public") with cherrypy.request.db_session() as session: project = cherrypy.request.project region = session.query(Region).filter( Region.id == request.region_id).first() if region is None: raise cherrypy.HTTPError( 404, "A region with the requested id does not exist.") if region.state != RegionState.CREATED: raise cherrypy.HTTPError( 412, "The requested region is not in the following state: %s" % RegionState.CREATED.value) image = session.query(Image).filter( Image.project_id == project.id).filter( Image.name == request.name).filter( Image.region_id == region.id).first() if image is not None: raise cherrypy.HTTPError( 409, 'An image with the requested name already exists.') image = session.query(Image).filter( Image.project_id == project.id).filter( Image.file_name == request.file_name).first() if image is not None: raise cherrypy.HTTPError( 409, 'An image with the requested file already exists.') image = Image() image.name = request.name image.file_name = request.file_name image.visibility = request.visibility image.project_id = project.id image.region_id = region.id session.add(image) session.flush() create_task(session, image, create_image, image_id=image.id) session.commit() session.refresh(image) return ResponseImage.from_database(image)
def action_image(self, instance_id: uuid.UUID): request: RequestInstanceImage = cherrypy.request.model if request.visibility == ImageVisibility.PUBLIC: self.mount.enforce_policy("instances:action:image:public") with cherrypy.request.db_session() as session: instance: Instance = session.merge( cherrypy.request.resource_object, load=False) if instance.state != InstanceState.STOPPED: raise cherrypy.HTTPError( 409, "Can only image an instance in the following state: %s" % InstanceState.STOPPED.value) region = session.query(Region).filter( Region.id == instance.region_id).one() image = session.query(Image).filter( Image.project_id == instance.project_id).filter( Image.name == request.name).filter( Image.region_id == region.id).first() if image is not None: raise cherrypy.HTTPError( 409, 'An image with the requested name already exists.') instance.state = InstanceState.IMAGING image = Image() image.name = request.name image.file_name = str(instance.id) image.visibility = request.visibility image.project_id = instance.project_id image.region_id = region.id session.add(image) session.flush() # Clone the vm to a template create_task(session, image, convert_vm, image_id=image.id, instance_id=instance.id) instance.current_task_id = image.current_task_id session.commit() return ResponseImage.from_database(image)
def create(self): request: RequestCreateNetwork = cherrypy.request.model with cherrypy.request.db_session() as session: network = session.query(Network).filter(Network.name == request.name).first() if network is not None: raise cherrypy.HTTPError(409, "A network with the requested name already exists.") network = session.query(Network).filter(Network.port_group == request.port_group).first() if network is not None: raise cherrypy.HTTPError(409, "A network with the requested port group already exists.") region = session.query(Region).filter(Region.id == request.region_id).first() if region is None: raise cherrypy.HTTPError(404, "A region with the requested id does not exist.") if region.state != RegionState.CREATED: raise cherrypy.HTTPError(412, "The requested region is not in the following state: %s" % RegionState.CREATED.value) # TODO: make sure cidr doesn't overlap with another network network = Network() network.name = request.name network.port_group = request.port_group network.cidr = request.cidr network.gateway = request.gateway network.dns_servers = request.dns_servers network.pool_start = request.pool_start network.pool_end = request.pool_end network.region_id = region.id session.add(network) session.flush() create_task(session, network, create_network, network_id=network.id) session.commit() session.refresh(network) return ResponseNetwork.from_database(network)
def create(self): request: RequestCreateZone = cherrypy.request.model with cherrypy.request.db_session() as session: zone = session.query(Zone).filter( Zone.name == request.name).first() if zone is not None: raise cherrypy.HTTPError( 409, 'A zone with the requested name already exists.') region = session.query(Region).filter( Region.id == request.region_id).first() if region is None: raise cherrypy.HTTPError( 404, "A region with the requested id does not exist.") if region.state != RegionState.CREATED: raise cherrypy.HTTPError( 412, "The requested region is not in the following state: %s" % RegionState.CREATED.value) zone = Zone() zone.name = request.name zone.region_id = region.id zone.vm_cluster = request.vm_cluster zone.vm_datastore = request.vm_datastore zone.core_provision_percent = request.core_provision_percent zone.ram_provision_percent = request.ram_provision_percent zone.schedulable = False if request.vm_folder is not None: zone.vm_folder = request.vm_folder session.add(zone) session.flush() create_task(session, zone, create_zone, zone_id=zone.id) session.commit() session.refresh(zone) return ResponseZone.from_database(zone)
def action_restart(self, instance_id: uuid.UUID): request: RequestInstancePowerOffRestart = cherrypy.request.model cherrypy.response.status = 202 with cherrypy.request.db_session() as session: instance: Instance = session.merge( cherrypy.request.resource_object, load=False) if instance.state != InstanceState.ACTIVE: raise cherrypy.HTTPError( 409, "Can only restart an instance in the following state: %s" % InstanceState.ACTIVE.value) instance.state = InstanceState.RESTARTING create_task(session, instance, restart_instance, instance_id=instance.id, hard=request.hard, timeout=request.timeout) session.commit()
def create(self): request: RequestCreateInstance = cherrypy.request.model with cherrypy.request.db_session() as session: project = cherrypy.request.project instance = session.query(Instance).filter( Instance.project_id == project.id).filter( Instance.name == request.name).first() if instance is not None: raise cherrypy.HTTPError( 409, 'An instance already exists with the requested name.') region = session.query(Region).filter( Region.id == request.region_id).first() if region is None: raise cherrypy.HTTPError( 404, "A region with the requested id does not exist.") if region.state != RegionState.CREATED: raise cherrypy.HTTPError( 412, "The requested region is not in the following state: %s" % RegionState.CREATED.value) if region.schedulable is False: raise cherrypy.HTTPError( 412, "The requested region is not currently schedulable.") image = session.query(Image).filter( Image.id == request.image_id).filter( Image.region_id == region.id).first() if image is None: raise cherrypy.HTTPError( 404, "An image with the requested id does not exist.") if image.state != ImageState.CREATED: raise cherrypy.HTTPError( 412, "The requested image is not in the '%s' state" % (ImageState.CREATED.value)) if image.project_id != project.id: if image.visibility == ImageVisibility.PRIVATE: raise cherrypy.HTTPError( 400, "The requested image does not belong to the scoped project." ) elif image.visibility == ImageVisibility.SHARED: if project not in image.members: raise cherrypy.HTTPError( 400, "The requested image is not shared with the scoped project." ) elif image.visibility == ImageVisibility.PUBLIC: # Image is public so don't error pass if request.service_account_id is not None: service_account: AuthNServiceAccount = session.query( AuthNServiceAccount).filter( AuthNServiceAccount.id == request.service_account_id).first() if service_account is None: raise cherrypy.HTTPError( 404, "A service account with the requested id does not exist." ) if service_account.project_id != project.id: raise cherrypy.HTTPError( 400, "The requested service account does not belong to the scoped project." ) else: service_account = session.query(AuthNServiceAccount).filter( AuthNServiceAccount.project_id == project.id).filter( AuthNServiceAccount.name == "default").first() network = session.query(Network).filter( Network.id == request.network_id).filter( Network.region_id == region.id).first() if network is None: raise cherrypy.HTTPError( 404, "A network with the requested id does not exist.") if network.state != NetworkState.CREATED: raise cherrypy.HTTPError( 412, "The requested network is not in the '%s' state" % (NetworkState.CREATED.value)) zone = None if request.zone_id is not None: zone = session.query(Zone).filter( Zone.id == request.zone_id).filter( Zone.region_id == region.id).first() if zone is None: raise cherrypy.HTTPError( 404, "A zone with the requested id does not exist.") if zone.state != ZoneState.CREATED: raise cherrypy.HTTPError( 412, "The requested zone is not in the following state: %s" % ZoneState.CREATED.value) if zone.schedulable is False: raise cherrypy.HTTPError( 412, "The requested zone is not currently schedulable.") network_port = NetworkPort() network_port.network_id = network.id network_port.project_id = project.id session.add(network_port) session.flush() instance = Instance() instance.name = request.name instance.image_id = image.id instance.project_id = project.id instance.network_port_id = network_port.id instance.tags = request.tags instance.service_account_id = service_account.id instance.region_id = region.id if zone is not None: instance.zone_id = zone.id session.add(instance) session.flush() for keypair_id in request.keypair_ids: keypair = session.query(Keypair).filter( Keypair.id == keypair_id).filter( Keypair.project_id == project.id).first() if keypair is None: raise cherrypy.HTTPError( 404, "Could not find a keypair within the scoped project with the id %s" % keypair_id) instance.keypairs.append(keypair) print("TASK") create_task(session, instance, create_instance, instance_id=instance.id) response = ResponseInstance.from_database(instance) session.commit() return response