Remove devfile validation schema mechanism (#640)
Remove devfile validation schema mechanism and related stuff.pull/643/head
parent
3fb1df91f7
commit
12a3a8a8e7
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -215,7 +215,6 @@ public class WsMasterModule extends AbstractModule {
|
|||
bind(WorkspaceEntityProvider.class);
|
||||
bind(org.eclipse.che.api.workspace.server.TemporaryWorkspaceRemover.class);
|
||||
bind(org.eclipse.che.api.workspace.server.WorkspaceService.class);
|
||||
bind(org.eclipse.che.api.devfile.server.DevfileService.class);
|
||||
bind(org.eclipse.che.api.devfile.server.UserDevfileEntityProvider.class);
|
||||
|
||||
install(new FactoryModuleBuilder().build(ServersCheckerFactory.class));
|
||||
|
|
|
|||
|
|
@ -38,10 +38,6 @@
|
|||
<groupId>jakarta.inject</groupId>
|
||||
<artifactId>jakarta.inject-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.ws.rs</groupId>
|
||||
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-api-account</artifactId>
|
||||
|
|
@ -82,10 +78,6 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.everrest</groupId>
|
||||
<artifactId>everrest-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -16,13 +16,11 @@ import com.google.inject.multibindings.Multibinder;
|
|||
import com.google.inject.name.Names;
|
||||
import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
|
||||
import org.eclipse.che.multiuser.api.permission.shared.model.PermissionsDomain;
|
||||
import org.eclipse.che.multiuser.permission.devfile.server.filters.UserDevfilePermissionsFilter;
|
||||
|
||||
public class UserDevfileApiPermissionsModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(UserDevfilePermissionsFilter.class);
|
||||
bind(UserDevfileCreatorPermissionsProvider.class).asEagerSingleton();
|
||||
|
||||
Multibinder.newSetBinder(
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.multiuser.permission.devfile.server.filters;
|
||||
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DELETE;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.DOMAIN_ID;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.READ;
|
||||
import static org.eclipse.che.multiuser.permission.devfile.server.UserDevfileDomain.UPDATE;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import jakarta.ws.rs.Path;
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.api.core.ForbiddenException;
|
||||
import org.eclipse.che.api.devfile.server.DevfileService;
|
||||
import org.eclipse.che.api.devfile.server.UserDevfileManager;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.everrest.CheMethodInvokerFilter;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.resource.GenericResourceMethod;
|
||||
|
||||
/**
|
||||
* Restricts access to methods of {@link DevfileService} by users' permissions.
|
||||
*
|
||||
* <p>Filter contains rules for protecting of all methods of {@link DevfileService}.<br>
|
||||
* In case when requested method is unknown filter throws {@link ForbiddenException}
|
||||
*/
|
||||
@Filter
|
||||
@Path("/devfile{path:(/.*)?}")
|
||||
public class UserDevfilePermissionsFilter extends CheMethodInvokerFilter {
|
||||
private final UserDevfileManager userDevfileManager;
|
||||
|
||||
@Inject
|
||||
public UserDevfilePermissionsFilter(UserDevfileManager userDevfileManager) {
|
||||
this.userDevfileManager = userDevfileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(GenericResourceMethod genericResourceMethod, Object[] arguments)
|
||||
throws ForbiddenException {
|
||||
final String methodName = genericResourceMethod.getMethod().getName();
|
||||
switch (methodName) {
|
||||
case "getById":
|
||||
doCheckPermission(DOMAIN_ID, ((String) arguments[0]), READ);
|
||||
break;
|
||||
case "update":
|
||||
doCheckPermission(DOMAIN_ID, ((String) arguments[0]), UPDATE);
|
||||
break;
|
||||
case "delete":
|
||||
doCheckPermission(DOMAIN_ID, ((String) arguments[0]), DELETE);
|
||||
break;
|
||||
case "createFromDevfileYaml":
|
||||
case "createFromUserDevfile":
|
||||
case "getUserDevfiles":
|
||||
case "getSchema":
|
||||
return;
|
||||
default:
|
||||
throw new ForbiddenException("The user does not have permission to perform this operation");
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void doCheckPermission(String domain, String instance, String action) throws ForbiddenException {
|
||||
EnvironmentContext.getCurrent().getSubject().checkPermission(domain, instance, action);
|
||||
}
|
||||
}
|
||||
|
|
@ -39,10 +39,6 @@
|
|||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-persist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations-jakarta</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.annotation</groupId>
|
||||
<artifactId>jakarta.annotation-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SUPPORTED_VERSIONS;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
import org.eclipse.che.api.core.rest.Service;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
|
||||
/** Defines Devfile REST API. */
|
||||
@Deprecated
|
||||
@Tag(name = "devfile", description = "Devfile REST API")
|
||||
@Path("/devfile")
|
||||
public class DevfileService extends Service {
|
||||
|
||||
private final DevfileSchemaProvider schemaCachedProvider;
|
||||
|
||||
@Inject
|
||||
public DevfileService(DevfileSchemaProvider schemaCachedProvider) {
|
||||
this.schemaCachedProvider = schemaCachedProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the json schema.
|
||||
*
|
||||
* @return json schema
|
||||
*/
|
||||
@GET
|
||||
@Produces(APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Retrieves current version of devfile JSON schema",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The schema successfully retrieved"),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "The schema for given version was not found"),
|
||||
@ApiResponse(responseCode = "500", description = "Internal server error occurred")
|
||||
})
|
||||
public Response getSchema(
|
||||
@Parameter(description = "Devfile schema version")
|
||||
@DefaultValue(CURRENT_API_VERSION)
|
||||
@QueryParam("version")
|
||||
String version)
|
||||
throws ServerException, NotFoundException {
|
||||
if (!SUPPORTED_VERSIONS.contains(version)) {
|
||||
throw new NotFoundException(
|
||||
String.format(
|
||||
"Devfile schema version '%s' is invalid or not supported. Supported versions are '%s'.",
|
||||
version, SUPPORTED_VERSIONS));
|
||||
}
|
||||
|
||||
try {
|
||||
return Response.ok(schemaCachedProvider.getSchemaContent(version)).build();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new NotFoundException(e.getLocalizedMessage());
|
||||
} catch (IOException e) {
|
||||
throw new ServerException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import jakarta.ws.rs.HttpMethod;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.util.LinksHelper;
|
||||
import org.eclipse.che.api.devfile.shared.Constants;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
|
||||
/** Helps to inject {@link DevfileService} related links. */
|
||||
@Beta
|
||||
@Singleton
|
||||
public class DevfileServiceLinksInjector {
|
||||
public UserDevfileDto injectLinks(UserDevfileDto userDevfileDto, ServiceContext serviceContext) {
|
||||
return userDevfileDto.withLinks(
|
||||
ImmutableList.of(
|
||||
LinksHelper.createLink(
|
||||
HttpMethod.GET,
|
||||
serviceContext
|
||||
.getBaseUriBuilder()
|
||||
.clone()
|
||||
.path(DevfileService.class)
|
||||
.path(DevfileService.class, "getById")
|
||||
.build(userDevfileDto.getId())
|
||||
.toString(),
|
||||
null,
|
||||
APPLICATION_JSON,
|
||||
Constants.LINK_REL_SELF)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.devfile.server;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.eclipse.che.api.devfile.server.TestObjectGenerator.TEST_SUBJECT;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SUPPORTED_VERSIONS;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
|
||||
import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
|
||||
import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import io.restassured.response.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.eclipse.che.api.core.notification.EventService;
|
||||
import org.eclipse.che.api.core.rest.ApiExceptionMapper;
|
||||
import org.eclipse.che.api.core.rest.CheJsonProvider;
|
||||
import org.eclipse.che.api.core.rest.ServiceContext;
|
||||
import org.eclipse.che.api.core.rest.WebApplicationExceptionMapper;
|
||||
import org.eclipse.che.api.devfile.server.spi.UserDevfileDao;
|
||||
import org.eclipse.che.api.devfile.shared.dto.UserDevfileDto;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileEntityProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileVersionDetector;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.DevfileDto;
|
||||
import org.eclipse.che.api.workspace.shared.dto.devfile.MetadataDto;
|
||||
import org.eclipse.che.commons.env.EnvironmentContext;
|
||||
import org.eclipse.che.dto.server.DtoFactory;
|
||||
import org.everrest.assured.EverrestJetty;
|
||||
import org.everrest.core.Filter;
|
||||
import org.everrest.core.GenericContainerRequest;
|
||||
import org.everrest.core.RequestFilter;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.mockito.testng.MockitoTestNGListener;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
|
||||
public class DevfileServiceTest {
|
||||
|
||||
@SuppressWarnings("unused") // is declared for deploying by everrest-assured
|
||||
ApiExceptionMapper exceptionMapper = new ApiExceptionMapper();
|
||||
|
||||
WebApplicationExceptionMapper exceptionMapper2 = new WebApplicationExceptionMapper();
|
||||
|
||||
private DevfileSchemaProvider schemaProvider = new DevfileSchemaProvider();
|
||||
|
||||
private static final EnvironmentFilter FILTER = new EnvironmentFilter();
|
||||
|
||||
private DevfileParser devfileParser =
|
||||
new DevfileParser(
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider(), new DevfileVersionDetector()),
|
||||
new DevfileIntegrityValidator(Collections.emptyMap()));
|
||||
DevfileEntityProvider devfileEntityProvider = new DevfileEntityProvider(devfileParser);
|
||||
UserDevfileEntityProvider userDevfileEntityProvider =
|
||||
new UserDevfileEntityProvider(devfileParser);
|
||||
private CheJsonProvider jsonProvider = new CheJsonProvider(new HashSet<>());
|
||||
|
||||
@Mock UserDevfileDao userDevfileDao;
|
||||
@Mock UserDevfileManager userDevfileManager;
|
||||
@Mock EventService eventService;
|
||||
@Mock DevfileServiceLinksInjector linksInjector;
|
||||
|
||||
DevfileService userDevfileService;
|
||||
|
||||
@Test
|
||||
public void shouldRetrieveSchema() throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile");
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
assertEquals(
|
||||
response.getBody().asString(), schemaProvider.getSchemaContent(CURRENT_API_VERSION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturn404WhenSchemaNotFound() {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile?version=1.2.3.4.5");
|
||||
|
||||
assertEquals(response.getStatusCode(), 404);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "schemaVersions")
|
||||
public void shouldRetrieveSchemaVersion(String version) throws Exception {
|
||||
final Response response =
|
||||
given()
|
||||
.auth()
|
||||
.basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
|
||||
.when()
|
||||
.get(SECURE_PATH + "/devfile?version=" + version);
|
||||
|
||||
assertEquals(response.getStatusCode(), 200);
|
||||
assertEquals(response.getBody().asString(), schemaProvider.getSchemaContent(version));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] schemaVersions() {
|
||||
Object[][] versions = new Object[SUPPORTED_VERSIONS.size()][];
|
||||
for (int i = 0; i < SUPPORTED_VERSIONS.size(); i++) {
|
||||
versions[i] = new Object[] {SUPPORTED_VERSIONS.get(i)};
|
||||
}
|
||||
|
||||
return versions;
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setup() {
|
||||
this.userDevfileService = new DevfileService(schemaProvider);
|
||||
lenient()
|
||||
.when(linksInjector.injectLinks(any(UserDevfileDto.class), any(ServiceContext.class)))
|
||||
.thenAnswer((Answer<UserDevfileDto>) invocation -> invocation.getArgument(0));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] validUserDevfiles() {
|
||||
return new Object[][] {
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name")))
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName(null)
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name")))
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name")))
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion("1.0.0")
|
||||
.withMetadata(newDto(MetadataDto.class).withGenerateName("gen-")))
|
||||
},
|
||||
{DtoConverter.asDto(TestObjectGenerator.createUserDevfile())}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] invalidUserDevfiles() {
|
||||
return new Object[][] {
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(null),
|
||||
"Mandatory field `devfile` is not defined."
|
||||
},
|
||||
{
|
||||
newDto(UserDevfileDto.class)
|
||||
.withName("My devfile")
|
||||
.withDescription("Devfile description")
|
||||
.withDevfile(
|
||||
newDto(DevfileDto.class)
|
||||
.withApiVersion(null)
|
||||
.withMetadata(newDto(MetadataDto.class).withName("name"))),
|
||||
"Devfile schema validation failed. Error: Neither of `apiVersion` or `schemaVersion` found. This is not a valid devfile."
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> T unwrapDto(Response response, Class<T> dtoClass) {
|
||||
return DtoFactory.getInstance().createDtoFromJson(response.asString(), dtoClass);
|
||||
}
|
||||
|
||||
private static <T> List<T> unwrapDtoList(Response response, Class<T> dtoClass)
|
||||
throws IOException {
|
||||
return new ArrayList<>(
|
||||
DtoFactory.getInstance().createListDtoFromJson(response.body().asInputStream(), dtoClass));
|
||||
}
|
||||
|
||||
@Filter
|
||||
public static class EnvironmentFilter implements RequestFilter {
|
||||
|
||||
public void doFilter(GenericContainerRequest request) {
|
||||
EnvironmentContext.getCurrent().setSubject(TEST_SUBJECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -38,11 +38,9 @@ import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
|||
import org.eclipse.che.api.workspace.server.devfile.DevfileVersionDetector;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFileContentProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.ComponentIntegrityValidator.NoopComponentIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
|
@ -71,11 +69,6 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
@Test
|
||||
public void shouldResolveRelativeFiles() throws Exception {
|
||||
// given
|
||||
|
||||
// we need to set up an "almost real" devfile converter which is a little bit involved
|
||||
DevfileSchemaValidator validator =
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider(), new DevfileVersionDetector());
|
||||
|
||||
Map<String, ComponentIntegrityValidator> validators = new HashMap<>();
|
||||
validators.put(EDITOR_COMPONENT_TYPE, new NoopComponentIntegrityValidator());
|
||||
validators.put(PLUGIN_COMPONENT_TYPE, new NoopComponentIntegrityValidator());
|
||||
|
|
@ -84,7 +77,7 @@ public class RawDevfileUrlFactoryParameterResolverTest {
|
|||
|
||||
DevfileIntegrityValidator integrityValidator = new DevfileIntegrityValidator(validators);
|
||||
|
||||
DevfileParser devfileParser = new DevfileParser(validator, integrityValidator);
|
||||
DevfileParser devfileParser = new DevfileParser(integrityValidator);
|
||||
|
||||
URLFactoryBuilder factoryBuilder =
|
||||
new URLFactoryBuilder(
|
||||
|
|
|
|||
|
|
@ -126,19 +126,9 @@
|
|||
<groupId>org.eclipse.che.core</groupId>
|
||||
<artifactId>che-core-commons-tracing</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>jakarta.json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.leadpony.justify</groupId>
|
||||
<artifactId>justify</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jakarta.json-api</artifactId>
|
||||
<groupId>jakarta.json</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@
|
|||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Constants {
|
||||
|
||||
private Constants() {}
|
||||
|
|
@ -23,9 +21,6 @@ public class Constants {
|
|||
|
||||
public static final String CURRENT_API_VERSION = "1.0.0";
|
||||
|
||||
public static final List<String> SUPPORTED_VERSIONS =
|
||||
List.of(CURRENT_API_VERSION, "2.0.0", "2.1.0", "2.2.0", "2.2.1", "2.2.2");
|
||||
|
||||
public static final String EDITOR_COMPONENT_TYPE = "cheEditor";
|
||||
|
||||
public static final String PLUGIN_COMPONENT_TYPE = "chePlugin";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -36,7 +36,6 @@ import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
|
|||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.OverrideParameterException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.DevfileImpl;
|
||||
|
||||
|
|
@ -51,27 +50,19 @@ public class DevfileParser {
|
|||
|
||||
private final ObjectMapper yamlMapper;
|
||||
private final ObjectMapper jsonMapper;
|
||||
private final DevfileSchemaValidator schemaValidator;
|
||||
private final DevfileIntegrityValidator integrityValidator;
|
||||
private final OverridePropertiesApplier overridePropertiesApplier;
|
||||
|
||||
@Inject
|
||||
public DevfileParser(
|
||||
DevfileSchemaValidator schemaValidator, DevfileIntegrityValidator integrityValidator) {
|
||||
this(
|
||||
schemaValidator,
|
||||
integrityValidator,
|
||||
new ObjectMapper(new YAMLFactory()),
|
||||
new ObjectMapper());
|
||||
public DevfileParser(DevfileIntegrityValidator integrityValidator) {
|
||||
this(integrityValidator, new ObjectMapper(new YAMLFactory()), new ObjectMapper());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DevfileParser(
|
||||
DevfileSchemaValidator schemaValidator,
|
||||
DevfileIntegrityValidator integrityValidator,
|
||||
ObjectMapper yamlMapper,
|
||||
ObjectMapper jsonMapper) {
|
||||
this.schemaValidator = schemaValidator;
|
||||
this.integrityValidator = integrityValidator;
|
||||
this.yamlMapper = yamlMapper;
|
||||
this.jsonMapper = jsonMapper;
|
||||
|
|
@ -120,8 +111,7 @@ public class DevfileParser {
|
|||
* @param devfileJson json with devfile content
|
||||
* @return devfile in simple Map structure
|
||||
*/
|
||||
public Map<String, Object> convertYamlToMap(JsonNode devfileJson) throws DevfileFormatException {
|
||||
schemaValidator.validate(devfileJson);
|
||||
public Map<String, Object> convertYamlToMap(JsonNode devfileJson) {
|
||||
return yamlMapper.convertValue(devfileJson, new TypeReference<>() {});
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +205,6 @@ public class DevfileParser {
|
|||
DevfileImpl devfile;
|
||||
try {
|
||||
parsed = overridePropertiesApplier.applyPropertiesOverride(parsed, overrideProperties);
|
||||
schemaValidator.validate(parsed);
|
||||
devfile = mapper.treeToValue(parsed, DevfileImpl.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new DevfileFormatException(e.getMessage());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -12,11 +12,8 @@
|
|||
package org.eclipse.che.api.workspace.server.devfile.convert;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Components.getIdentifiableComponentName;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SUPPORTED_VERSIONS;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import org.eclipse.che.api.core.ServerException;
|
||||
|
|
@ -104,8 +101,6 @@ public class DevfileConverter {
|
|||
// make copy to avoid modification of original devfile
|
||||
devfile = new DevfileImpl(devfile);
|
||||
|
||||
validateCurrentVersion(devfile);
|
||||
|
||||
defaultEditorProvisioner.apply(devfile, contentProvider);
|
||||
|
||||
WorkspaceConfigImpl config = new WorkspaceConfigImpl();
|
||||
|
|
@ -143,17 +138,4 @@ public class DevfileConverter {
|
|||
|
||||
return config;
|
||||
}
|
||||
|
||||
private static void validateCurrentVersion(Devfile devFile) throws DevfileFormatException {
|
||||
if (Strings.isNullOrEmpty(devFile.getApiVersion())) {
|
||||
throw new DevfileFormatException("Provided Devfile has no API version specified");
|
||||
}
|
||||
if (SUPPORTED_VERSIONS.stream().noneMatch(v -> v.equals(devFile.getApiVersion()))) {
|
||||
throw new DevfileFormatException(
|
||||
format(
|
||||
"Provided Devfile has unsupported version '%s'. The following versions are"
|
||||
+ " supported: %s",
|
||||
devFile.getApiVersion(), SUPPORTED_VERSIONS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile.schema;
|
||||
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SCHEMAS_LOCATION;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SCHEMA_FILENAME;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SUPPORTED_VERSIONS;
|
||||
import static org.eclipse.che.commons.lang.IoUtil.getResource;
|
||||
import static org.eclipse.che.commons.lang.IoUtil.readAndCloseQuietly;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/** Loads a schema content and stores it in soft reference. */
|
||||
@Singleton
|
||||
public class DevfileSchemaProvider {
|
||||
|
||||
private final Map<String, SoftReference<String>> schemas = new HashMap<>();
|
||||
|
||||
public String getSchemaContent(String version) throws IOException {
|
||||
if (schemas.containsKey(version)) {
|
||||
String schema = schemas.get(version).get();
|
||||
if (schema != null) {
|
||||
return schema;
|
||||
} else {
|
||||
return loadAndPut(version);
|
||||
}
|
||||
} else {
|
||||
return loadAndPut(version);
|
||||
}
|
||||
}
|
||||
|
||||
public StringReader getAsReader(String version) throws IOException {
|
||||
return new StringReader(getSchemaContent(version));
|
||||
}
|
||||
|
||||
private String loadFile(String version) throws IOException {
|
||||
try {
|
||||
return readAndCloseQuietly(getResource(SCHEMAS_LOCATION + version + "/" + SCHEMA_FILENAME));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new FileNotFoundException(
|
||||
String.format(
|
||||
"Unable to find schema for devfile version '%s'. Supported versions are '%s'.",
|
||||
version, SUPPORTED_VERSIONS));
|
||||
} catch (IOException ioe) {
|
||||
throw new IOException(
|
||||
String.format(
|
||||
"Unable to load devfile schema with version '%s'. Supported versions are '%s'",
|
||||
version, SUPPORTED_VERSIONS),
|
||||
ioe);
|
||||
}
|
||||
}
|
||||
|
||||
private String loadAndPut(String version) throws IOException {
|
||||
final String schema = loadFile(version);
|
||||
schemas.put(version, new SoftReference<>(schema));
|
||||
return schema;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile.validator;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.SUPPORTED_VERSIONS;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.json.JsonReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileVersionDetector;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.leadpony.justify.api.JsonSchema;
|
||||
import org.leadpony.justify.api.JsonValidationService;
|
||||
import org.leadpony.justify.api.Problem;
|
||||
import org.leadpony.justify.api.ProblemHandler;
|
||||
|
||||
/** Validates YAML devfile content against given JSON schema. */
|
||||
@Singleton
|
||||
public class DevfileSchemaValidator {
|
||||
|
||||
private final JsonValidationService service;
|
||||
private final ObjectMapper jsonMapper;
|
||||
private final Map<String, JsonSchema> schemasByVersion;
|
||||
private final ErrorMessageComposer errorMessageComposer;
|
||||
private final DevfileVersionDetector devfileVersionDetector;
|
||||
|
||||
@Inject
|
||||
public DevfileSchemaValidator(
|
||||
DevfileSchemaProvider schemaProvider, DevfileVersionDetector devfileVersionDetector) {
|
||||
this.service = JsonValidationService.newInstance();
|
||||
this.jsonMapper = new ObjectMapper();
|
||||
this.errorMessageComposer = new ErrorMessageComposer();
|
||||
this.devfileVersionDetector = devfileVersionDetector;
|
||||
try {
|
||||
this.schemasByVersion = new HashMap<>();
|
||||
for (String version : SUPPORTED_VERSIONS) {
|
||||
this.schemasByVersion.put(version, service.readSchema(schemaProvider.getAsReader(version)));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unable to read devfile json schema for validation.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void validate(JsonNode contentNode) throws DevfileFormatException {
|
||||
try {
|
||||
List<Problem> validationErrors = new ArrayList<>();
|
||||
ProblemHandler handler = ProblemHandler.collectingTo(validationErrors);
|
||||
String devfileVersion = devfileVersionDetector.devfileVersion(contentNode);
|
||||
|
||||
if (!schemasByVersion.containsKey(devfileVersion)) {
|
||||
throw new DevfileFormatException(
|
||||
String.format(
|
||||
"Version '%s' of the devfile is not supported. Supported versions are '%s'.",
|
||||
devfileVersion, SUPPORTED_VERSIONS));
|
||||
}
|
||||
JsonSchema schema = schemasByVersion.get(devfileVersion);
|
||||
try (JsonReader reader =
|
||||
service.createReader(
|
||||
new StringReader(jsonMapper.writeValueAsString(contentNode)), schema, handler)) {
|
||||
reader.read();
|
||||
}
|
||||
if (!validationErrors.isEmpty()) {
|
||||
String error = errorMessageComposer.extractMessages(validationErrors, new StringBuilder());
|
||||
throw new DevfileFormatException(error);
|
||||
}
|
||||
} catch (DevfileException dfe) {
|
||||
throw new DevfileFormatException(
|
||||
format("Devfile schema validation failed. Error: %s", dfe.getMessage()));
|
||||
} catch (IOException e) {
|
||||
throw new DevfileFormatException("Unable to validate Devfile. Error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,871 +0,0 @@
|
|||
{
|
||||
"meta:license": [
|
||||
" Copyright (c) 2012-2019 Red Hat, Inc.",
|
||||
" This program and the accompanying materials are made",
|
||||
" available under the terms of the Eclipse Public License 2.0",
|
||||
" which is available at https://www.eclipse.org/legal/epl-2.0/",
|
||||
" SPDX-License-Identifier: EPL-2.0",
|
||||
" Contributors:",
|
||||
" Red Hat, Inc. - initial API and implementation"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"title": "Devfile object",
|
||||
"description": "This schema describes the structure of the devfile object",
|
||||
"definitions": {
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"apiVersion",
|
||||
"metadata"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"const": "1.0.0",
|
||||
"title": "Devfile API Version"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Devfile Name",
|
||||
"description": "The name of the devfile. Workspaces created from devfile, will inherit this name",
|
||||
"examples": [
|
||||
"petclinic-dev-environment"
|
||||
]
|
||||
},
|
||||
"generateName": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Devfile Generate Name",
|
||||
"description": "Workspaces created from devfile, will use it as base and append random suffix. It's used when name is not defined.",
|
||||
"examples": [
|
||||
"petclinic-"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"generateName"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"projects": {
|
||||
"type": "array",
|
||||
"title": "The Projects List",
|
||||
"description": "Description of the projects, containing names and sources locations",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"source"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "The Project Name",
|
||||
"examples": [
|
||||
"petclinic"
|
||||
]
|
||||
},
|
||||
"source": {
|
||||
"type": "object",
|
||||
"title": "The Project Source object",
|
||||
"description": "Describes the project's source - type and location",
|
||||
"required": [
|
||||
"type",
|
||||
"location"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Project's source type.",
|
||||
"examples": [
|
||||
"git",
|
||||
"github",
|
||||
"zip"
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "Project's source location address. Should be URL for git and github located projects, or file:// for zip.",
|
||||
"examples": [
|
||||
"git@github.com:spring-projects/spring-petclinic.git"
|
||||
]
|
||||
},
|
||||
"branch": {
|
||||
"type": "string",
|
||||
"description": "The name of the of the branch to check out after obtaining the source from the location. The branch has to already exist in the source otherwise the default branch is used. In case of git, this is also the name of the remote branch to push to.",
|
||||
"examples": [
|
||||
"master",
|
||||
"feature-42"
|
||||
]
|
||||
},
|
||||
"startPoint": {
|
||||
"type": "string",
|
||||
"description": "The tag or commit id to reset the checked out branch to.",
|
||||
"examples": [
|
||||
"release/4.2",
|
||||
"349d3ad",
|
||||
"v4.2.0"
|
||||
]
|
||||
},
|
||||
"tag": {
|
||||
"type": "string",
|
||||
"description": "The name of the tag to reset the checked out branch to. Note that this is equivalent to 'startPoint' and provided for convenience.",
|
||||
"examples": [
|
||||
"v4.2.0"
|
||||
]
|
||||
},
|
||||
"commitId": {
|
||||
"type": "string",
|
||||
"description": "The id of the commit to reset the checked out branch to. Note that this is equivalent to 'startPoint' and provided for convenience.",
|
||||
"examples": [
|
||||
"349d3ad"
|
||||
]
|
||||
},
|
||||
"sparseCheckoutDir": {
|
||||
"type": "string",
|
||||
"description": "Part of project to populate in the working directory.",
|
||||
"examples": [
|
||||
"/core/",
|
||||
"core/",
|
||||
"core",
|
||||
"/wsmaster/che-core-api-workspace/",
|
||||
"/d*"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"clonePath": {
|
||||
"type": "string",
|
||||
"description": "The path relative to the root of the projects to which this project should be cloned into. This is a unix-style relative path (i.e. uses forward slashes). The path is invalid if it is absolute or tries to escape the project root through the usage of '..'. If not specified, defaults to the project name."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"type": "array",
|
||||
"title": "The Components List",
|
||||
"description": "Description of the workspace components, such as editor and plugins",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"cheEditor",
|
||||
"chePlugin"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"oneOf": [
|
||||
{
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"not": {
|
||||
"required": [
|
||||
"reference"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"reference"
|
||||
],
|
||||
"not": {
|
||||
"required": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {},
|
||||
"alias": {},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Describes the component id. It has the following format: {plugin/editor PUBLISHER}/{plugin/editor NAME}/{plugin/editor VERSION}",
|
||||
"pattern": "[a-z0-9_\\-.]+/[a-z0-9_\\-.]+/[a-z0-9_\\-.]+$",
|
||||
"examples": [
|
||||
"eclipse/maven-jdk8/1.0.0"
|
||||
]
|
||||
},
|
||||
"reference": {
|
||||
"description": "Describes raw location of plugin yaml file.",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"https://pastebin.com/raw/kYprWiNB"
|
||||
]
|
||||
},
|
||||
"registryUrl": {
|
||||
"description": "Describes URL of custom plugin registry.",
|
||||
"type": "string",
|
||||
"pattern": "^(https?://)[a-zA-Z0-9_\\-./]+",
|
||||
"examples": [
|
||||
"https://che-plugin-registry.openshift.io/v3/"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"cheEditor"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {},
|
||||
"alias": {},
|
||||
"id": {},
|
||||
"env": {},
|
||||
"endpoints": {},
|
||||
"volumes": {},
|
||||
"reference": {},
|
||||
"registryUrl": {},
|
||||
"memoryLimit": {},
|
||||
"memoryRequest": {},
|
||||
"automountWorkspaceSecrets": {},
|
||||
"cpuLimit": {},
|
||||
"cpuRequest": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"chePlugin"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {},
|
||||
"alias": {},
|
||||
"id": {},
|
||||
"env": {},
|
||||
"endpoints": {},
|
||||
"volumes": {},
|
||||
"memoryLimit": {},
|
||||
"memoryRequest": {},
|
||||
"automountWorkspaceSecrets": {},
|
||||
"cpuLimit": {},
|
||||
"cpuRequest": {},
|
||||
"reference": {},
|
||||
"registryUrl": {},
|
||||
"preferences": {
|
||||
"type": "object",
|
||||
"description": "Additional plugin preferences",
|
||||
"examples": [
|
||||
"{\"java.home\": \"/home/user/jdk11\", \"java.jdt.ls.vmargs\": \"-Xmx1G\"}"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": [
|
||||
"boolean",
|
||||
"string",
|
||||
"number"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"string",
|
||||
"number"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"kubernetes",
|
||||
"openshift"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"reference"
|
||||
],
|
||||
"additionalProperties": true
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"referenceContent"
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {},
|
||||
"alias": {},
|
||||
"mountSources": {},
|
||||
"automountWorkspaceSecrets": {},
|
||||
"volumes": {},
|
||||
"env": {},
|
||||
"endpoints": {},
|
||||
"reference": {
|
||||
"description": "Describes absolute or devfile-relative location of Kubernetes list yaml file. Applicable only for 'kubernetes' and 'openshift' type components",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"petclinic-app.yaml"
|
||||
]
|
||||
},
|
||||
"referenceContent": {
|
||||
"description": "Inlined content of a file specified in field 'reference'",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"{\"kind\":\"List\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"ws\"},\"spec\":{\"containers\":[{\"image\":\"quay.io/eclipse/che-dev:nightly\"}]}}]}"
|
||||
]
|
||||
},
|
||||
"selector": {
|
||||
"$ref": "#/definitions/selector",
|
||||
"description": "Describes the objects selector for the recipe type components. Allows to pick-up only selected items from k8s/openshift list",
|
||||
"examples": [
|
||||
"{\n \"app.kubernetes.io/name\" : \"mysql\", \n \"app.kubernetes.io/component\" : \"database\", \n \"app.kubernetes.io/part-of\" : \"petclinic\" \n}"
|
||||
]
|
||||
},
|
||||
"entrypoints": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parentName": {
|
||||
"type": "string",
|
||||
"description": "The name of the top level object in the referenced object list in which to search for containers. If not specified, the objects to search through can have any name."
|
||||
},
|
||||
"containerName": {
|
||||
"type": "string",
|
||||
"description": "The name of the container to apply the entrypoint to. If not specified, the entrypoint is modified on all matching containers."
|
||||
},
|
||||
"parentSelector": {
|
||||
"$ref": "#/definitions/selector",
|
||||
"description": "The selector on labels of the top level objects in the referenced list in which to search for containers. If not specified, the objects to search through can have any labels."
|
||||
},
|
||||
"command": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": null,
|
||||
"description": "The command to run in the component instead of the default one provided in the image of the container. Defaults to null, meaning use whatever is defined in the image.",
|
||||
"examples": [
|
||||
"['/bin/sh', '-c']"
|
||||
]
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": null,
|
||||
"description": "The arguments to supply to the command running the component. The arguments are supplied either to the default command provided in the image of the container or to the overridden command. Defaults to null, meaning use whatever is defined in the image.",
|
||||
"examples": [
|
||||
"['-R', '-f']"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"dockerimage"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"required": [
|
||||
"image",
|
||||
"memoryLimit"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {},
|
||||
"alias": {},
|
||||
"mountSources": {},
|
||||
"env": {},
|
||||
"cpuLimit": {},
|
||||
"cpuRequest": {},
|
||||
"automountWorkspaceSecrets": {},
|
||||
"volumes": {},
|
||||
"endpoints": {},
|
||||
"memoryLimit": {},
|
||||
"memoryRequest": {},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"description": "Specifies the docker image that should be used for component",
|
||||
"examples": [
|
||||
"eclipse/maven-jdk8:1.0.0"
|
||||
]
|
||||
},
|
||||
"command": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": null,
|
||||
"description": "The command to run in the dockerimage component instead of the default one provided in the image. Defaults to null, meaning use whatever is defined in the image.",
|
||||
"examples": [
|
||||
"['/bin/sh', '-c']"
|
||||
]
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": null,
|
||||
"description": "The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. Defaults to null, meaning use whatever is defined in the image.",
|
||||
"examples": [
|
||||
"['-R', '-f']"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"alias": {
|
||||
"description": "The name using which other places of this devfile (like commands) can refer to this component. This attribute is optional but must be unique in the devfile if specified.",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"mvn-stack"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"description": "Describes type of the component, e.g. whether it is an plugin or editor or other type",
|
||||
"enum": [
|
||||
"cheEditor",
|
||||
"chePlugin",
|
||||
"kubernetes",
|
||||
"openshift",
|
||||
"dockerimage"
|
||||
],
|
||||
"examples": [
|
||||
"chePlugin",
|
||||
"cheEditor",
|
||||
"kubernetes",
|
||||
"openshift",
|
||||
"dockerimage"
|
||||
]
|
||||
},
|
||||
"mountSources": {
|
||||
"type": "boolean",
|
||||
"description": "Describes whether projects sources should be mount to the component. `CHE_PROJECTS_ROOT` environment variable should contains a path where projects sources are mount",
|
||||
"default": "false"
|
||||
},
|
||||
"memoryLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"exclusiveMinimum": 0
|
||||
}
|
||||
],
|
||||
"description": "Describes memory limit for the component. You can express memory as a plain integer or as a fixed-point integer using one of these suffixes: E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki",
|
||||
"examples": [
|
||||
"128974848",
|
||||
"129e6",
|
||||
"129M",
|
||||
"123Mi"
|
||||
]
|
||||
},
|
||||
"memoryRequest": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"exclusiveMinimum": 0
|
||||
}
|
||||
],
|
||||
"description": "Describes memory request for the component. You can express memory as a plain integer or as a fixed-point integer using one of these suffixes: E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki",
|
||||
"examples": [
|
||||
"128974848",
|
||||
"129e6",
|
||||
"129M",
|
||||
"123Mi"
|
||||
]
|
||||
},
|
||||
"cpuLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
}
|
||||
],
|
||||
"description": "Describes CPU limit for the component. You can express CPU limit as a float-point cores or as a fixed-point integer millicores using 'm' suffix",
|
||||
"examples": [
|
||||
"2",
|
||||
"0.235",
|
||||
"100m",
|
||||
"1230m"
|
||||
]
|
||||
},
|
||||
"cpuRequest": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
}
|
||||
],
|
||||
"description": "Describes CPU request for the component. You can express CPU request as a float-point cores or as a fixed-point integer millicores using 'm' suffix",
|
||||
"examples": [
|
||||
"2",
|
||||
"0.235",
|
||||
"100m",
|
||||
"1230m"
|
||||
]
|
||||
},
|
||||
"automountWorkspaceSecrets": {
|
||||
"type": "boolean",
|
||||
"description": "Describes whether namespace secrets should be mount to the component."
|
||||
},
|
||||
"volumes": {
|
||||
"type": "array",
|
||||
"description": "Describes volumes which should be mount to component",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describe volume that should be mount to component",
|
||||
"required": [
|
||||
"name",
|
||||
"containerPath"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "The Volume Name",
|
||||
"description": "The volume name. If several components mount the same volume then they will reuse the volume and will be able to access to the same files",
|
||||
"examples": [
|
||||
"my-data"
|
||||
]
|
||||
},
|
||||
"containerPath": {
|
||||
"type": "string",
|
||||
"title": "The path where volume should be mount to container",
|
||||
"examples": [
|
||||
"/home/user/data"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
"type": "array",
|
||||
"description": "The environment variables list that should be set to docker container",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes environment variable",
|
||||
"required": [
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "The Environment Variable Name",
|
||||
"description": "The environment variable name"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"title": "The Environment Variable Value",
|
||||
"description": "The environment variable value"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"endpoints": {
|
||||
"type": "array",
|
||||
"description": "Describes dockerimage component endpoints",
|
||||
"items": {
|
||||
"name": "object",
|
||||
"description": "Describes dockerimage component endpoint",
|
||||
"required": [
|
||||
"name",
|
||||
"port"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "The Endpoint Name",
|
||||
"description": "The Endpoint name"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer",
|
||||
"title": "The Endpoint Port",
|
||||
"description": "The container port that should be used as endpoint"
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"public": {
|
||||
"type": "boolean",
|
||||
"description": "Identifies endpoint as workspace internally or externally accessible.",
|
||||
"default": "true"
|
||||
},
|
||||
"secure": {
|
||||
"type": "boolean",
|
||||
"description": "Identifies server as secure or non-secure. Requests to secure servers will be authenticated and must contain machine token",
|
||||
"default": "false"
|
||||
},
|
||||
"discoverable": {
|
||||
"type": "boolean",
|
||||
"description": "Identifies endpoint as accessible by its name.",
|
||||
"default": "false"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "boolean",
|
||||
"description": "Defines protocol that should be used for communication with endpoint. Is used for endpoint URL evaluation"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"javaType": "java.util.Map<String, String>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"type": "array",
|
||||
"title": "The Commands List",
|
||||
"description": "Description of the predefined commands to be available in workspace",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"name",
|
||||
"actions"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Describes the name of the command. Should be unique per commands set.",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"attributes": {
|
||||
"description": "Additional command attributes",
|
||||
"$ref": "#/definitions/attributes"
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"description": "List of the actions of given command. Now the only one command must be specified in list but there are plans to implement supporting multiple actions commands.",
|
||||
"title": "The Command Actions List",
|
||||
"minItems": 1,
|
||||
"maxItems": 1,
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"type": {},
|
||||
"component": {},
|
||||
"command": {},
|
||||
"workdir": {}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"component",
|
||||
"command"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {},
|
||||
"reference": {},
|
||||
"referenceContent": {}
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"type",
|
||||
"reference"
|
||||
],
|
||||
"additionalProperties": true
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"type",
|
||||
"referenceContent"
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "Describes action type",
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"exec",
|
||||
"vscode-task",
|
||||
"vscode-launch"
|
||||
]
|
||||
},
|
||||
"component": {
|
||||
"type": "string",
|
||||
"description": "Describes component to which given action relates",
|
||||
"examples": [
|
||||
"mvn-stack"
|
||||
]
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "The actual action command-line string",
|
||||
"examples": [
|
||||
"mvn package"
|
||||
]
|
||||
},
|
||||
"workdir": {
|
||||
"type": "string",
|
||||
"description": "Working directory where the command should be executed",
|
||||
"examples": [
|
||||
"/projects/spring-petclinic"
|
||||
]
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "the path relative to the location of the devfile to the configuration file defining one or more actions in the editor-specific format",
|
||||
"examples": [
|
||||
"../ide-config/launch.json"
|
||||
]
|
||||
},
|
||||
"referenceContent": {
|
||||
"type": "string",
|
||||
"description": "The content of the referenced configuration file that defines one or more actions in the editor-specific format",
|
||||
"examples": [
|
||||
"{\"version\": \"2.0.0\",\n \"tasks\": [\n {\n \"type\": \"typescript\",\n \"tsconfig\": \"tsconfig.json\",\n \"problemMatcher\": [\n \"$tsc\"\n ],\n \"group\": {\n \"kind\": \"build\",\n \"isDefault\": true\n }\n }\n ]}"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"previewUrl": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"port"
|
||||
],
|
||||
"properties": {
|
||||
"port": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 65535
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"editorFree": {
|
||||
"type": "boolean",
|
||||
"description": "Defines that no editor is needed and default one should not be provisioned. Defaults to `false`.",
|
||||
"default": "false"
|
||||
},
|
||||
"persistVolumes": {
|
||||
"type": "boolean",
|
||||
"description": "Defines whether volumes should be stored or not. Defaults to `true`. In case of `false` workspace volumes will be created as `emptyDir`. The data in the `emptyDir` volume is deleted forever when a workspace Pod is removed for any reason(pod is crashed, workspace is restarted).",
|
||||
"default": "true"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -73,11 +73,8 @@ import org.eclipse.che.api.core.rest.CheJsonProvider;
|
|||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileEntityProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileParser;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileVersionDetector;
|
||||
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.MachineConfigImpl;
|
||||
|
|
@ -158,9 +155,7 @@ public class WorkspaceServiceTest {
|
|||
@SuppressWarnings("unused") // is declared for deploying by everrest-assured
|
||||
private DevfileEntityProvider devfileEntityProvider =
|
||||
new DevfileEntityProvider(
|
||||
new DevfileParser(
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider(), new DevfileVersionDetector()),
|
||||
new DevfileIntegrityValidator(Collections.emptyMap())));
|
||||
new DevfileParser(new DevfileIntegrityValidator(Collections.emptyMap())));
|
||||
|
||||
@Mock private WorkspaceManager wsManager;
|
||||
@Mock private MachineTokenProvider machineTokenProvider;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -31,7 +31,6 @@ import java.io.IOException;
|
|||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileIntegrityValidator;
|
||||
import org.eclipse.che.api.workspace.server.devfile.validator.DevfileSchemaValidator;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ActionImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.ComponentImpl;
|
||||
|
|
@ -47,8 +46,6 @@ import org.testng.annotations.Test;
|
|||
public class DevfileParserTest {
|
||||
|
||||
private static final String DEVFILE_YAML_CONTENT = "devfile yaml stub";
|
||||
|
||||
@Mock private DevfileSchemaValidator schemaValidator;
|
||||
@Mock private DevfileIntegrityValidator integrityValidator;
|
||||
@Mock private ObjectMapper jsonMapper;
|
||||
@Mock private ObjectMapper yamlMapper;
|
||||
|
|
@ -62,7 +59,7 @@ public class DevfileParserTest {
|
|||
@BeforeMethod
|
||||
public void setUp() throws Exception {
|
||||
devfile = new DevfileImpl();
|
||||
devfileParser = new DevfileParser(schemaValidator, integrityValidator, yamlMapper, jsonMapper);
|
||||
devfileParser = new DevfileParser(integrityValidator, yamlMapper, jsonMapper);
|
||||
|
||||
lenient().when(jsonMapper.treeToValue(any(), eq(DevfileImpl.class))).thenReturn(devfile);
|
||||
lenient().when(yamlMapper.treeToValue(any(), eq(DevfileImpl.class))).thenReturn(devfile);
|
||||
|
|
@ -77,7 +74,6 @@ public class DevfileParserTest {
|
|||
// then
|
||||
assertEquals(parsed, devfile);
|
||||
verify(yamlMapper).treeToValue(devfileJsonNode, DevfileImpl.class);
|
||||
verify(schemaValidator).validate(eq(devfileJsonNode));
|
||||
verify(integrityValidator).validateDevfile(devfile);
|
||||
}
|
||||
|
||||
|
|
@ -175,17 +171,6 @@ public class DevfileParserTest {
|
|||
// then exception is thrown
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = DevfileFormatException.class,
|
||||
expectedExceptionsMessageRegExp = "non valid")
|
||||
public void shouldThrowExceptionWhenExceptionOccurredDuringSchemaValidation() throws Exception {
|
||||
// given
|
||||
doThrow(new DevfileFormatException("non valid")).when(schemaValidator).validate(any());
|
||||
|
||||
// when
|
||||
devfileParser.parseYaml(DEVFILE_YAML_CONTENT);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = DevfileFormatException.class,
|
||||
expectedExceptionsMessageRegExp = "non valid")
|
||||
|
|
@ -206,7 +191,6 @@ public class DevfileParserTest {
|
|||
devfileParser.convertYamlToMap(devfileJsonNode);
|
||||
|
||||
// then
|
||||
verify(schemaValidator).validate(eq(devfileJsonNode));
|
||||
verify(yamlMapper).convertValue(eq(devfileJsonNode), any(TypeReference.class));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -32,7 +32,6 @@ import org.eclipse.che.api.workspace.server.devfile.FileContentProvider;
|
|||
import org.eclipse.che.api.workspace.server.devfile.URLFetcher;
|
||||
import org.eclipse.che.api.workspace.server.devfile.convert.component.ComponentToWorkspaceApplier;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.ProjectConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.devfile.CommandImpl;
|
||||
|
|
@ -177,38 +176,6 @@ public class DevfileConverterTest {
|
|||
verify(componentToWorkspaceApplier).apply(workspaceConfig, component, fileContentProvider);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = DevfileFormatException.class,
|
||||
expectedExceptionsMessageRegExp = "Provided Devfile has no API version specified")
|
||||
public void
|
||||
shouldThrowAnExceptionIfDevfileApiVersionIsMissingDuringConvertingDevfileToWorkspaceConfig()
|
||||
throws Exception {
|
||||
// given
|
||||
FileContentProvider fileContentProvider = mock(FileContentProvider.class);
|
||||
DevfileImpl devfile = new DevfileImpl();
|
||||
devfile.setName("petclinic");
|
||||
|
||||
// when
|
||||
devfileConverter.devFileToWorkspaceConfig(devfile, fileContentProvider);
|
||||
}
|
||||
|
||||
@Test(
|
||||
expectedExceptions = DevfileFormatException.class,
|
||||
expectedExceptionsMessageRegExp =
|
||||
"Provided Devfile has unsupported version '1\\.0\\.0-non-supported'. The following versions are supported: .*")
|
||||
public void
|
||||
shouldThrowAnExceptionIfDevfileApiVersionIsNotSupportedDuringConvertingDevfileToWorkspaceConfig()
|
||||
throws Exception {
|
||||
// given
|
||||
FileContentProvider fileContentProvider = mock(FileContentProvider.class);
|
||||
DevfileImpl devfile = new DevfileImpl();
|
||||
devfile.setApiVersion("1.0.0-non-supported");
|
||||
devfile.setName("petclinic");
|
||||
|
||||
// when
|
||||
devfileConverter.devFileToWorkspaceConfig(devfile, fileContentProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertDevfileToWorkspaceConfig() throws Exception {
|
||||
devfileConverter = spy(devfileConverter);
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2021 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile.schema;
|
||||
|
||||
import static org.eclipse.che.api.workspace.server.devfile.Constants.CURRENT_API_VERSION;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class DevfileSchemaProviderTest {
|
||||
|
||||
private final DevfileSchemaProvider devfileSchemaProvider = new DevfileSchemaProvider();
|
||||
|
||||
@Test
|
||||
public void shouldGetProperDevfileSchemaContent() throws IOException {
|
||||
String content = devfileSchemaProvider.getSchemaContent(CURRENT_API_VERSION);
|
||||
assertNotNull(content);
|
||||
assertTrue(content.contains("This schema describes the structure of the devfile object"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetProperDevfileSchemaContentAsReader() throws IOException {
|
||||
StringReader contentReader = devfileSchemaProvider.getAsReader(CURRENT_API_VERSION);
|
||||
assertNotNull(contentReader);
|
||||
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
int c;
|
||||
while ((c = contentReader.read()) != -1) {
|
||||
contentBuilder.append((char) c);
|
||||
}
|
||||
assertTrue(
|
||||
contentBuilder
|
||||
.toString()
|
||||
.contains("This schema describes the structure of the devfile object"));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = FileNotFoundException.class)
|
||||
public void shouldThrowExceptionWhenInvalidVersionRequested() throws IOException {
|
||||
devfileSchemaProvider.getSchemaContent("this_is_clearly_not_a_valid_schema_version");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,293 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2024 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat, Inc. - initial API and implementation
|
||||
*/
|
||||
package org.eclipse.che.api.workspace.server.devfile.validator;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import java.io.IOException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.Constants;
|
||||
import org.eclipse.che.api.workspace.server.devfile.DevfileVersionDetector;
|
||||
import org.eclipse.che.api.workspace.server.devfile.exception.DevfileFormatException;
|
||||
import org.eclipse.che.api.workspace.server.devfile.schema.DevfileSchemaProvider;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.reporters.Files;
|
||||
|
||||
public class DevfileSchemaValidatorTest {
|
||||
|
||||
private DevfileSchemaValidator schemaValidator;
|
||||
private ObjectMapper yamlMapper;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() {
|
||||
yamlMapper = new ObjectMapper(new YAMLFactory());
|
||||
schemaValidator =
|
||||
new DevfileSchemaValidator(new DevfileSchemaProvider(), new DevfileVersionDetector());
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validDevfiles")
|
||||
public void shouldNotThrowExceptionOnValidationOfValidDevfile(String resourceFilePath)
|
||||
throws Exception {
|
||||
schemaValidator.validate(yamlMapper.readTree(getResource(resourceFilePath)));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] validDevfiles() {
|
||||
return new Object[][] {
|
||||
{"editor_plugin_component/devfile_editor_plugins.yaml"},
|
||||
{"editor_plugin_component/devfile_editor_component_with_custom_registry.yaml"},
|
||||
{"editor_plugin_component/devfile_editor_plugins_components_with_resource_limits.yaml"},
|
||||
{"editor_plugin_component/devfile_plugin_components_with_preferences.yaml"},
|
||||
{"kubernetes_openshift_component/devfile_kubernetes_component.yaml"},
|
||||
{"kubernetes_openshift_component/devfile_kubernetes_component_absolute_reference.yaml"},
|
||||
{"component/devfile_without_any_component.yaml"},
|
||||
{"component/devfile_component_with_automount_secrets.yaml"},
|
||||
{
|
||||
"kubernetes_openshift_component/devfile_kubernetes_component_reference_and_content_as_block.yaml"
|
||||
},
|
||||
{"kubernetes_openshift_component/devfile_openshift_component.yaml"},
|
||||
{"kubernetes_openshift_component/devfile_openshift_component_reference_and_content.yaml"},
|
||||
{
|
||||
"kubernetes_openshift_component/devfile_openshift_component_reference_and_content_as_block.yaml"
|
||||
},
|
||||
{"kubernetes_openshift_component/devfile_k8s_openshift_component_with_env.yaml"},
|
||||
{"kubernetes_openshift_component/devfile_k8s_openshift_component_with_endpoints.yaml"},
|
||||
{"kubernetes_openshift_component/devfile_openshift_component_content_without_reference.yaml"},
|
||||
{
|
||||
"kubernetes_openshift_component/devfile_kubernetes_component_content_without_reference.yaml"
|
||||
},
|
||||
{"dockerimage_component/devfile_dockerimage_component.yaml"},
|
||||
{"dockerimage_component/devfile_dockerimage_component_without_entry_point.yaml"},
|
||||
{"editor_plugin_component/devfile_editor_component_with_custom_registry.yaml"},
|
||||
{"editor_plugin_component/devfile_plugin_component_with_reference.yaml"},
|
||||
{"devfile/devfile_just_generatename.yaml"},
|
||||
{"devfile/devfile_name_and_generatename.yaml"},
|
||||
{"devfile/devfile_with_sparse_checkout_dir.yaml"},
|
||||
{"devfile/devfile_name_and_generatename.yaml"},
|
||||
{"command/devfile_command_with_preview_url.yaml"},
|
||||
{"command/devfile_command_with_preview_url_only_port.yaml"},
|
||||
{"devfile/devfile_v2_just_schemaVersion.yaml"},
|
||||
{"devfile/devfile_v2_sample-devfile.yaml"},
|
||||
{"devfile/devfile_v2_simple-devfile.yaml"},
|
||||
{"devfile/devfile_v2_spring-boot-http-booster-devfile.yaml"},
|
||||
{"devfile/devfile_v2-1-0_just_schemaVersion.yaml"},
|
||||
{"devfile/devfile_v2-1-0_simple-devfile.yaml"},
|
||||
{"devfile/devfile_v2-2-0-simple-devfile.yaml"},
|
||||
{"devfile/devfile_v2-2-0-quarkus.yaml"},
|
||||
{"devfile/devfile_v2-2-0-basic-nodejs.yaml"},
|
||||
{"devfile/devfile_v2-2-0-basic-python.yaml"},
|
||||
{"devfile/devfile_v2-2-0-basic-quarkus.yaml"},
|
||||
{"devfile/devfile_v2-2-0-basic-springboot.yaml"}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidDevfiles")
|
||||
public void shouldThrowExceptionOnValidationOfNonValidDevfile(
|
||||
String resourceFilePath, String expectedMessage) throws Exception {
|
||||
try {
|
||||
schemaValidator.validate(yamlMapper.readTree(getResource(resourceFilePath)));
|
||||
} catch (DevfileFormatException e) {
|
||||
assertEquals(
|
||||
e.getMessage(),
|
||||
format("Devfile schema validation failed. Error: %s", expectedMessage),
|
||||
"DevfileFormatException thrown with message that doesn't match expected message:");
|
||||
return;
|
||||
}
|
||||
fail("DevfileFormatException expected to be thrown but is was not");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenDevfileHasUnsupportedApiVersion() throws Exception {
|
||||
try {
|
||||
String devfile =
|
||||
"---\n" + "apiVersion: 111.111\n" + "metadata:\n" + " name: test-invalid-apiversion\n";
|
||||
schemaValidator.validate(yamlMapper.readTree(devfile));
|
||||
} catch (DevfileFormatException e) {
|
||||
assertEquals(
|
||||
e.getMessage(),
|
||||
"Devfile schema validation failed. Error: Version '111.111' of the devfile is not supported. "
|
||||
+ "Supported versions are '"
|
||||
+ Constants.SUPPORTED_VERSIONS
|
||||
+ "'.");
|
||||
return;
|
||||
}
|
||||
fail("DevfileFormatException expected to be thrown but is was not");
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] invalidDevfiles() {
|
||||
return new Object[][] {
|
||||
// Devfile model testing
|
||||
{
|
||||
"devfile/devfile_empty_metadata.yaml",
|
||||
"At least one of the following sets of problems must be resolved.: [(/metadata):The object must have a property whose name is \"name\".(/metadata):The object must have a property whose name is \"generateName\".]"
|
||||
},
|
||||
{
|
||||
"devfile/devfile_null_metadata.yaml",
|
||||
"(/metadata):The value must be of object type, but actual type is null."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_missing_metadata.yaml",
|
||||
"The object must have a property whose name is \"metadata\"."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_missing_name_and_generatename.yaml",
|
||||
"(/metadata/something):The object must not have a property whose name is \"something\".At least one of the following sets of problems must be resolved.: [(/metadata):The object must have a property whose name is \"name\".(/metadata):The object must have a property whose name is \"generateName\".]"
|
||||
},
|
||||
{
|
||||
"devfile/devfile_missing_api_version.yaml",
|
||||
"Neither of `apiVersion` or `schemaVersion` found. This is not a valid devfile."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_with_undeclared_field.yaml",
|
||||
"(/unknown):The object must not have a property whose name is \"unknown\"."
|
||||
},
|
||||
// component model testing
|
||||
{
|
||||
"component/devfile_missing_component_type.yaml",
|
||||
"(/components/0):The object must have a property whose name is \"type\"."
|
||||
},
|
||||
{
|
||||
"component/devfile_unknown_component_type.yaml",
|
||||
"(/components/0/type):The value must be one of [\"cheEditor\", \"chePlugin\", \"kubernetes\", \"openshift\", \"dockerimage\"]."
|
||||
},
|
||||
{
|
||||
"component/devfile_component_with_undeclared_field.yaml",
|
||||
"(/components/0/unknown):The object must not have a property whose name is \"unknown\"."
|
||||
},
|
||||
// Command model testing
|
||||
{
|
||||
"command/devfile_missing_command_name.yaml",
|
||||
"(/commands/0):The object must have a property whose name is \"name\"."
|
||||
},
|
||||
{
|
||||
"command/devfile_missing_command_actions.yaml",
|
||||
"(/commands/0):The object must have a property whose name is \"actions\"."
|
||||
},
|
||||
{
|
||||
"command/devfile_multiple_commands_actions.yaml",
|
||||
"(/commands/0/actions):The array must have at most 1 element(s), but actual number is 2."
|
||||
},
|
||||
{
|
||||
"command/devfile_action_without_commandline_and_reference.yaml",
|
||||
"Exactly one of the following sets of problems must be resolved.: [(/commands/0/actions/0):The object must have a property whose name is \"component\".(/commands/0/actions/0):The object must have a property whose name is \"command\".At least one of the following sets of problems must be resolved.: [(/commands/0/actions/0):The object must have a property whose name is \"reference\".(/commands/0/actions/0):The object must have a property whose name is \"referenceContent\".]]"
|
||||
},
|
||||
// cheEditor/chePlugin component model testing
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_with_missing_id.yaml",
|
||||
"Exactly one of the following sets of problems must be resolved.: [(/components/0):The object must have a property whose name is \"id\".(/components/0):The object must have a property whose name is \"reference\".]"
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_with_id_and_reference.yaml",
|
||||
"Exactly one of the following sets of problems must be resolved.: "
|
||||
+ "[(/components/0):The object must not have a property whose name is \"reference\"."
|
||||
+ "(/components/0):The object must not have a property whose name is \"id\".]"
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_with_indistinctive_field.yaml",
|
||||
"(/components/0/unknown):The object must not have a property whose name is \"unknown\"."
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_without_version.yaml",
|
||||
"(/components/0/id):The string value must match the pattern \"[a-z0-9_\\-.]+/[a-z0-9_\\-.]+/[a-z0-9_\\-.]+\\z\"."
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_plugins_components_with_invalid_memory_limit.yaml",
|
||||
"At least one of the following sets of problems must be resolved.: [(/components/0/memoryLimit):The value must be of string type, but actual type is integer.(/components/0/memoryLimit):The numeric value must be greater than 0.]At least one of the following sets of problems must be resolved.: [(/components/1/memoryLimit):The value must be of string type, but actual type is integer.(/components/1/memoryLimit):The numeric value must be greater than 0.]"
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_with_multiple_colons_in_id.yaml",
|
||||
"(/components/0/id):The string value must match the pattern \"[a-z0-9_\\-.]+/[a-z0-9_\\-.]+/[a-z0-9_\\-.]+\\z\"."
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_with_registry_in_id.yaml",
|
||||
"(/components/0/id):The string value must match the pattern \"[a-z0-9_\\-.]+/[a-z0-9_\\-.]+/[a-z0-9_\\-.]+\\z\"."
|
||||
},
|
||||
{
|
||||
"editor_plugin_component/devfile_editor_component_with_bad_registry.yaml",
|
||||
"(/components/0/registryUrl):The string value must match the pattern \"^(https?://)[a-zA-Z0-9_\\-./]+\"."
|
||||
},
|
||||
// kubernetes/openshift component model testing
|
||||
{
|
||||
"kubernetes_openshift_component/devfile_openshift_component_with_missing_reference_and_referenceContent.yaml",
|
||||
"At least one of the following sets of problems must be resolved.: [(/components/0):The object must have a property whose name is \"reference\".(/components/0):The object must have a property whose name is \"referenceContent\".]"
|
||||
},
|
||||
{
|
||||
"kubernetes_openshift_component/devfile_openshift_component_with_indistinctive_field_id.yaml",
|
||||
"(/components/0/id):The object must not have a property whose name is \"id\"."
|
||||
},
|
||||
// Dockerimage component model testing
|
||||
{
|
||||
"dockerimage_component/devfile_dockerimage_component_with_missing_image.yaml",
|
||||
"(/components/0):The object must have a property whose name is \"image\"."
|
||||
},
|
||||
{
|
||||
"dockerimage_component/devfile_dockerimage_component_with_missing_memory_limit.yaml",
|
||||
"(/components/0):The object must have a property whose name is \"memoryLimit\"."
|
||||
},
|
||||
{
|
||||
"dockerimage_component/devfile_dockerimage_component_with_invalid_memory_limit.yaml",
|
||||
"At least one of the following sets of problems must be resolved.: [(/components/0/memoryLimit):The value must be of string type, but actual type is integer.(/components/0/memoryLimit):The numeric value must be greater than 0.]"
|
||||
},
|
||||
{
|
||||
"dockerimage_component/devfile_dockerimage_component_with_indistinctive_field_selector.yaml",
|
||||
"(/components/0/selector):The object must not have a property whose name is \"selector\"."
|
||||
},
|
||||
{
|
||||
"command/devfile_command_with_empty_preview_url.yaml",
|
||||
"(/commands/0/previewUrl):The value must be of object type, but actual type is null."
|
||||
},
|
||||
{
|
||||
"command/devfile_command_with_preview_url_port_is_string.yaml",
|
||||
"(/commands/0/previewUrl/port):The value must be of number type, but actual type is string."
|
||||
},
|
||||
{
|
||||
"command/devfile_command_with_preview_url_port_is_too_high.yaml",
|
||||
"(/commands/0/previewUrl/port):The numeric value must be less than or equal to 65535."
|
||||
},
|
||||
{
|
||||
"command/devfile_command_with_preview_url_port_is_negative.yaml",
|
||||
"(/commands/0/previewUrl/port):The numeric value must be greater than or equal to 0."
|
||||
},
|
||||
{
|
||||
"command/devfile_command_with_preview_url_only_path.yaml",
|
||||
"(/commands/0/previewUrl):The object must have a property whose name is \"port\"."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_v2_invalid_schemaVersion.yaml",
|
||||
"Version 'a.b.c' of the devfile is not supported. Supported versions are '[1.0.0, 2.0.0, 2.1.0, 2.2.0, 2.2.1, 2.2.2]'."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_v2_unsupported_schemaVersion.yaml",
|
||||
"Version '22.33.44' of the devfile is not supported. Supported versions are '[1.0.0, 2.0.0, 2.1.0, 2.2.0, 2.2.1, 2.2.2]'."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_v2-1-0_unsupported_schemaVersion.yaml",
|
||||
"Version '2.1.0-beta' of the devfile is not supported. Supported versions are '[1.0.0, 2.0.0, 2.1.0, 2.2.0, 2.2.1, 2.2.2]'."
|
||||
},
|
||||
{
|
||||
"devfile/devfile_v2-1-0_with_invalid_plugin_definition.yaml",
|
||||
"(/components/0/plugin):The object must not have a property whose name is \"plugin\".(/components/0):The object must have a property whose name is \"name\".Exactly one of the following sets of problems must be resolved.: [(/components/0):The object must have a property whose name is \"container\".(/components/0):The object must have a property whose name is \"kubernetes\".(/components/0):The object must have a property whose name is \"openshift\".(/components/0):The object must have a property whose name is \"volume\".]"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String getResource(String name) throws IOException {
|
||||
return Files.readFile(
|
||||
getClass().getClassLoader().getResourceAsStream("devfile/schema_test/" + name));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue