Search in sources :

Example 1 with AirflowException

use of io.hops.hopsworks.exceptions.AirflowException in project hopsworks by logicalclocks.

the class AirflowManager method prepareSecurityMaterial.

@Lock(LockType.READ)
@AccessTimeout(value = 1, unit = TimeUnit.SECONDS)
public void prepareSecurityMaterial(Users user, Project project, String[] audience) throws AirflowException {
    isInitialized();
    MaterializedJWTID materialID = new MaterializedJWTID(project.getId(), user.getUid(), MaterializedJWTID.USAGE.AIRFLOW);
    if (!materializedJWTFacade.exists(materialID)) {
        LocalDateTime expirationDate = DateUtils.getNow().plus(settings.getJWTLifetimeMs(), ChronoUnit.MILLIS);
        AirflowJWT airflowJWT = new AirflowJWT(user.getUsername(), project.getId(), project.getName(), expirationDate, user.getUid());
        try {
            String[] roles = getUserRoles(user);
            MaterializedJWT airflowMaterial = new MaterializedJWT(new MaterializedJWTID(project.getId(), user.getUid(), MaterializedJWTID.USAGE.AIRFLOW));
            materializedJWTFacade.persist(airflowMaterial);
            Map<String, Object> claims = new HashMap<>(3);
            claims.put(Constants.RENEWABLE, false);
            claims.put(Constants.EXPIRY_LEEWAY, settings.getJWTExpLeewaySec());
            claims.put(Constants.ROLES, roles);
            String token = jwtController.createToken(settings.getJWTSigningKeyName(), false, settings.getJWTIssuer(), audience, DateUtils.localDateTime2Date(expirationDate), DateUtils.localDateTime2Date(DateUtils.getNow()), user.getUsername(), claims, SignatureAlgorithm.valueOf(settings.getJWTSignatureAlg()));
            String projectAirflowDir = getProjectSecretsDirectory(user.getUsername()).toString();
            airflowJWT.tokenFile = Paths.get(projectAirflowDir, getTokenFileName(project.getName(), user.getUsername()));
            airflowJWT.token = token;
            writeTokenToFile(airflowJWT);
            certificateMaterializer.materializeCertificatesLocalCustomDir(user.getUsername(), project.getName(), projectAirflowDir);
            airflowJWTs.add(airflowJWT);
        } catch (GeneralSecurityException | JWTException ex) {
            deleteAirflowMaterial(materialID);
            throw new AirflowException(RESTCodes.AirflowErrorCode.JWT_NOT_CREATED, Level.SEVERE, "Could not generate Airflow JWT for user " + user.getUsername(), ex.getMessage(), ex);
        } catch (IOException ex) {
            LOG.log(Level.WARNING, "Could not write Airflow JWT for user " + hdfsUsersController.getHdfsUserName(project, user), ex);
            deleteAirflowMaterial(materialID);
            try {
                jwtController.invalidate(airflowJWT.token);
            } catch (InvalidationException invEx) {
                LOG.log(Level.FINE, "Could not invalidate Airflow JWT. Skipping...", ex);
            }
            throw new AirflowException(RESTCodes.AirflowErrorCode.JWT_NOT_STORED, Level.SEVERE, "Could not store Airflow JWT for user " + hdfsUsersController.getHdfsUserName(project, user), ex.getMessage(), ex);
        }
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) HashMap(java.util.HashMap) JWTException(io.hops.hopsworks.jwt.exception.JWTException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) MaterializedJWT(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT) MaterializedJWTID(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID) AirflowException(io.hops.hopsworks.exceptions.AirflowException) InvalidationException(io.hops.hopsworks.jwt.exception.InvalidationException) AccessTimeout(javax.ejb.AccessTimeout) Lock(javax.ejb.Lock)

Example 2 with AirflowException

use of io.hops.hopsworks.exceptions.AirflowException in project hopsworks by logicalclocks.

the class AirflowService method composeDAG.

@POST
@Path("/dag")
@Produces(MediaType.APPLICATION_JSON)
@AllowedProjectRoles({ AllowedProjectRoles.DATA_OWNER, AllowedProjectRoles.DATA_SCIENTIST })
@JWTRequired(acceptedTokens = { Audience.API }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
@ApiOperation(value = "Generate an Airflow Python DAG file from a DAG definition")
public Response composeDAG(AirflowDagDTO dagDefinition, @Context SecurityContext sc) throws AirflowException {
    Users user = jwtHelper.getUserPrincipal(sc);
    AirflowDAG dag = AirflowDagDTO.toAirflowDagTemplate(dagDefinition, user, project);
    Map<String, Object> dataModel = new HashMap<>(4);
    dataModel.put(AirflowJobLaunchOperator.class.getSimpleName(), AirflowJobLaunchOperator.class);
    dataModel.put(AirflowJobSuccessSensor.class.getSimpleName(), AirflowJobSuccessSensor.class);
    dataModel.put("dag", dag);
    java.nio.file.Path outputFile = Paths.get(airflowJWTManager.getProjectDagDirectory(project.getId()).toString(), dagDefinition.getName() + ".py");
    try (FileWriter out = new FileWriter(outputFile.toFile(), false)) {
        templateEngine.template(AirflowDAG.TEMPLATE_NAME, dataModel, out);
    } catch (IOException | TemplateException ex) {
        throw new AirflowException(RESTCodes.AirflowErrorCode.DAG_NOT_TEMPLATED, Level.SEVERE, "Could not template DAG file for Project " + project.getName(), ex.getMessage(), ex);
    }
    return Response.ok().build();
}
Also used : AirflowDAG(io.hops.hopsworks.common.util.templates.airflow.AirflowDAG) HashMap(java.util.HashMap) TemplateException(freemarker.template.TemplateException) FileWriter(java.io.FileWriter) AirflowJobLaunchOperator(io.hops.hopsworks.common.util.templates.airflow.AirflowJobLaunchOperator) Users(io.hops.hopsworks.persistence.entity.user.Users) AirflowJobSuccessSensor(io.hops.hopsworks.common.util.templates.airflow.AirflowJobSuccessSensor) IOException(java.io.IOException) AirflowException(io.hops.hopsworks.exceptions.AirflowException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) JWTRequired(io.hops.hopsworks.jwt.annotation.JWTRequired) ApiOperation(io.swagger.annotations.ApiOperation) AllowedProjectRoles(io.hops.hopsworks.api.filter.AllowedProjectRoles)

Example 3 with AirflowException

use of io.hops.hopsworks.exceptions.AirflowException in project hopsworks by logicalclocks.

the class AirflowService method secretDir.

@GET
@Path("secretDir")
@Produces(MediaType.TEXT_PLAIN)
@AllowedProjectRoles({ AllowedProjectRoles.DATA_OWNER, AllowedProjectRoles.DATA_SCIENTIST })
@JWTRequired(acceptedTokens = { Audience.API }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
@ApiOperation(value = "Create project secret directory in Airflow home")
public Response secretDir(@Context SecurityContext sc) throws AirflowException {
    String secret = DigestUtils.sha256Hex(Integer.toString(this.projectId));
    java.nio.file.Path dagsDir = airflowJWTManager.getProjectDagDirectory(project.getId());
    try {
        // Instead of checking and setting the permissions, just set them as it is an idempotent operation
        dagsDir.toFile().mkdirs();
        Files.setPosixFilePermissions(dagsDir, DAGS_PERM);
    } catch (IOException ex) {
        throw new AirflowException(RESTCodes.AirflowErrorCode.AIRFLOW_DIRS_NOT_CREATED, Level.SEVERE, "Could not create Airlflow directories", ex.getMessage(), ex);
    }
    return noCacheResponse.getNoCacheResponseBuilder(Response.Status.OK).entity(secret).build();
}
Also used : AirflowException(io.hops.hopsworks.exceptions.AirflowException) IOException(java.io.IOException) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) JWTRequired(io.hops.hopsworks.jwt.annotation.JWTRequired) ApiOperation(io.swagger.annotations.ApiOperation) AllowedProjectRoles(io.hops.hopsworks.api.filter.AllowedProjectRoles)

Aggregations

AirflowException (io.hops.hopsworks.exceptions.AirflowException)3 IOException (java.io.IOException)3 AllowedProjectRoles (io.hops.hopsworks.api.filter.AllowedProjectRoles)2 JWTRequired (io.hops.hopsworks.jwt.annotation.JWTRequired)2 ApiOperation (io.swagger.annotations.ApiOperation)2 HashMap (java.util.HashMap)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 TemplateException (freemarker.template.TemplateException)1 AirflowDAG (io.hops.hopsworks.common.util.templates.airflow.AirflowDAG)1 AirflowJobLaunchOperator (io.hops.hopsworks.common.util.templates.airflow.AirflowJobLaunchOperator)1 AirflowJobSuccessSensor (io.hops.hopsworks.common.util.templates.airflow.AirflowJobSuccessSensor)1 InvalidationException (io.hops.hopsworks.jwt.exception.InvalidationException)1 JWTException (io.hops.hopsworks.jwt.exception.JWTException)1 MaterializedJWT (io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT)1 MaterializedJWTID (io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID)1 Users (io.hops.hopsworks.persistence.entity.user.Users)1 FileWriter (java.io.FileWriter)1 GeneralSecurityException (java.security.GeneralSecurityException)1 LocalDateTime (java.time.LocalDateTime)1