use of org.eclipse.che.api.core.ValidationException in project che-server by eclipse-che.
the class KubernetesEnvironmentFactory method doCreate.
@Override
protected KubernetesEnvironment doCreate(@Nullable InternalRecipe recipe, Map<String, InternalMachineConfig> machines, List<Warning> sourceWarnings) throws InfrastructureException, ValidationException {
checkNotNull(recipe, "Null recipe is not supported by kubernetes environment factory");
List<Warning> warnings = new ArrayList<>();
if (sourceWarnings != null) {
warnings.addAll(sourceWarnings);
}
final List<HasMetadata> recipeObjects = recipeParser.parse(recipe);
Map<String, Pod> pods = new HashMap<>();
Map<String, Deployment> deployments = new HashMap<>();
Map<String, Service> services = new HashMap<>();
Map<String, ConfigMap> configMaps = new HashMap<>();
Map<String, PersistentVolumeClaim> pvcs = new HashMap<>();
Map<String, Secret> secrets = new HashMap<>();
boolean isAnyIngressPresent = false;
for (HasMetadata object : recipeObjects) {
checkNotNull(object.getKind(), "Environment contains object without specified kind field");
checkNotNull(object.getMetadata(), "%s metadata must not be null", object.getKind());
checkNotNull(object.getMetadata().getName(), "%s name must not be null", object.getKind());
if (object instanceof Pod) {
putInto(pods, object.getMetadata().getName(), (Pod) object);
} else if (object instanceof Deployment) {
putInto(deployments, object.getMetadata().getName(), (Deployment) object);
} else if (object instanceof Service) {
putInto(services, object.getMetadata().getName(), (Service) object);
} else if (object instanceof Ingress) {
isAnyIngressPresent = true;
} else if (object instanceof PersistentVolumeClaim) {
putInto(pvcs, object.getMetadata().getName(), (PersistentVolumeClaim) object);
} else if (object instanceof Secret) {
putInto(secrets, object.getMetadata().getName(), (Secret) object);
} else if (object instanceof ConfigMap) {
putInto(configMaps, object.getMetadata().getName(), (ConfigMap) object);
} else {
throw new ValidationException(format("Found unknown object type in recipe -- name: '%s', kind: '%s'", object.getMetadata().getName(), object.getKind()));
}
}
if (deployments.size() + pods.size() > 1) {
mergePods(pods, deployments, services);
}
if (isAnyIngressPresent) {
warnings.add(new WarningImpl(Warnings.INGRESSES_IGNORED_WARNING_CODE, Warnings.INGRESSES_IGNORED_WARNING_MESSAGE));
}
KubernetesEnvironment k8sEnv = KubernetesEnvironment.builder().setInternalRecipe(recipe).setMachines(machines).setWarnings(warnings).setPods(pods).setDeployments(deployments).setServices(services).setPersistentVolumeClaims(pvcs).setIngresses(new HashMap<>()).setSecrets(secrets).setConfigMaps(configMaps).build();
envValidator.validate(k8sEnv);
return k8sEnv;
}
use of org.eclipse.che.api.core.ValidationException in project che-server by eclipse-che.
the class KubernetesEnvironmentPodsValidator method validatePodVolumes.
private void validatePodVolumes(KubernetesEnvironment env) throws ValidationException {
Set<String> pvcsNames = env.getPersistentVolumeClaims().keySet();
for (PodData pod : env.getPodsData().values()) {
Set<String> volumesNames = new HashSet<>();
for (Volume volume : pod.getSpec().getVolumes()) {
volumesNames.add(volume.getName());
PersistentVolumeClaimVolumeSource pvcSource = volume.getPersistentVolumeClaim();
if (pvcSource != null && !pvcsNames.contains(pvcSource.getClaimName())) {
throw new ValidationException(String.format("Pod '%s' contains volume '%s' with PVC sources that references missing PVC '%s'", pod.getMetadata().getName(), volume.getName(), pvcSource.getClaimName()));
}
}
List<Container> containers = new ArrayList<>();
containers.addAll(pod.getSpec().getContainers());
containers.addAll(pod.getSpec().getInitContainers());
for (Container container : containers) {
for (VolumeMount volumeMount : container.getVolumeMounts()) {
if (!volumesNames.contains(volumeMount.getName())) {
throw new ValidationException(String.format("Container '%s' in pod '%s' contains volume mount that references missing volume '%s'", container.getName(), pod.getMetadata().getName(), volumeMount.getName()));
}
}
}
}
}
use of org.eclipse.che.api.core.ValidationException in project che-server by eclipse-che.
the class KubernetesRecipeParser method parse.
/**
* Parses Kubernetes objects from recipe content.
*
* @param recipeContent recipe content that should be parsed
* @return parsed objects
* @throws IllegalArgumentException if recipe content is null
* @throws ValidationException if recipe content has broken format
* @throws ValidationException if recipe content has unrecognized objects
* @throws InfrastructureException when exception occurred during kubernetes client creation
*/
public List<HasMetadata> parse(String recipeContent) throws ValidationException, InfrastructureException {
checkNotNull(recipeContent, "Recipe content type must not be null");
try {
// Behavior:
// - If `content` is a single object like Deployment, load().get() will get the object in that
// list
// - If `content` is a Kubernetes List, load().get() will get the objects in that list
// - If `content` is an OpenShift template, load().get() will get the objects in the template
// with parameters substituted (e.g. with default values).
List<HasMetadata> parsed = clientFactory.create().load(new ByteArrayInputStream(recipeContent.getBytes())).get();
// needed because Che master namespace is set by K8s API during list loading
parsed.stream().filter(o -> o.getMetadata() != null).forEach(o -> o.getMetadata().setNamespace(null));
return parsed;
} catch (KubernetesClientException e) {
// KubernetesClient wraps the error when a JsonMappingException occurs so we need the cause
String message = e.getCause() == null ? e.getMessage() : e.getCause().getMessage();
if (message.contains("\n")) {
// Clean up message if it comes from JsonMappingException. Format is e.g.
// `No resource type found for:v1#Route1\n at [...]`
message = message.split("\\n", 2)[0];
}
throw new ValidationException(format("Could not parse Kubernetes recipe: %s", message));
}
}
use of org.eclipse.che.api.core.ValidationException in project che-server by eclipse-che.
the class BrokerStatusListenerTest method shouldSubmitErrorWhenDoneEventIsReceivedButToolingIsValidationFails.
@Test
public void shouldSubmitErrorWhenDoneEventIsReceivedButToolingIsValidationFails() throws Exception {
// given
doThrow(new ValidationException("test")).when(validator).validatePluginNames(anyList());
BrokerEvent event = new BrokerEvent().withRuntimeId(new RuntimeIdentityImpl(WORKSPACE_ID, null, null, null)).withStatus(BrokerStatus.DONE).withTooling(emptyList());
// when
brokerStatusListener.onEvent(event);
// then
verify(brokersResult).error(any(ValidationException.class));
}
use of org.eclipse.che.api.core.ValidationException in project che-server by eclipse-che.
the class BrokerStatusListenerTest method shouldNotCallAddResultWhenValidationFails.
@Test
public void shouldNotCallAddResultWhenValidationFails() throws Exception {
// given
doThrow(new ValidationException("test")).when(validator).validatePluginNames(anyList());
BrokerEvent event = new BrokerEvent().withRuntimeId(new RuntimeIdentityImpl(WORKSPACE_ID, null, null, null)).withStatus(BrokerStatus.DONE).withTooling(emptyList());
// when
brokerStatusListener.onEvent(event);
// then
verify(brokersResult, never()).setResult(anyList());
}
Aggregations