org.arquillian.cube.openshift.impl.client.OpenShiftClient Maven / Gradle / Ivy
package org.arquillian.cube.openshift.impl.client;
import io.fabric8.kubernetes.api.model.v2_5.HasMetadata;
import io.fabric8.kubernetes.api.model.v2_5.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.v2_5.KubernetesResource;
import io.fabric8.kubernetes.api.model.v2_5.Pod;
import io.fabric8.kubernetes.api.model.v2_5.PodBuilder;
import io.fabric8.kubernetes.api.model.v2_5.Service;
import io.fabric8.kubernetes.clnt.v2_5.Config;
import io.fabric8.openshift.api.model.v2_5.Build;
import io.fabric8.openshift.api.model.v2_5.BuildConfig;
import io.fabric8.openshift.api.model.v2_5.BuildConfigBuilder;
import io.fabric8.openshift.api.model.v2_5.BuildRequest;
import io.fabric8.openshift.api.model.v2_5.BuildRequestBuilder;
import io.fabric8.openshift.api.model.v2_5.ImageStream;
import io.fabric8.openshift.api.model.v2_5.ImageStreamBuilder;
import io.fabric8.openshift.clnt.v2_5.DefaultOpenShiftClient;
import io.fabric8.openshift.clnt.v2_5.NamespacedOpenShiftClient;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.arquillian.cube.openshift.impl.model.Template;
import org.arquillian.cube.openshift.impl.model.Template.TemplateImageRef;
import static org.arquillian.cube.openshift.impl.client.ResourceUtil.waitForStart;
public class OpenShiftClient {
private String namespace;
private NamespacedOpenShiftClient kubernetes;
private GitServer gitserver;
private boolean keepAliveGitServer;
public OpenShiftClient(Config config, String namespace, boolean keepAliveGitServer) {
this.kubernetes = new DefaultOpenShiftClient(config);
this.namespace = namespace;
this.keepAliveGitServer = keepAliveGitServer;
this.gitserver = new GitServer(this.getClient(), config, namespace);
}
public List clean(ResourceHolder holder) {
List exceptions = new ArrayList();
List resourcesToDelete = new ArrayList();
for (KubernetesResource resource : holder.getResources()) {
if (resource instanceof HasMetadata) {
resourcesToDelete.add((HasMetadata) resource);
}
}
try {
getClient().lists().delete(new KubernetesListBuilder().withItems(resourcesToDelete).build());
} catch (Exception e) {
exceptions.add(e);
}
return exceptions;
}
public ResourceHolder build(Template template) throws Exception {
ResourceHolder holder = new ResourceHolder();
Map defaultLabels = getDefaultLabels();
if (template.getRefs().size() == 0) {
Pod service = createStartablePod(template, defaultLabels);
holder.setPod(service);
return holder;
}
for (TemplateImageRef ref : template.getRefs()) {
URI repoUri = gitserver.push(new File(ref.getPath()), ref.getContainerName());
String runID = ref.getContainerName();
try {
ImageStream is = new ImageStreamBuilder()
.withNewMetadata()
.withName(runID)
.withNamespace(namespace)
.withLabels(defaultLabels)
.endMetadata()
.build();
is = getClientExt().imageStreams().createOrReplace(is);
holder.addResource(is);
BuildConfig config = new BuildConfigBuilder()
.withNewMetadata()
.withName(runID)
.withNamespace(namespace)
.withLabels(defaultLabels)
.endMetadata()
.withNewSpec()
.withNewSource()
.withNewGit()
.withUri(repoUri.toString())
.withRef("master")
.endGit()
.endSource()
.withNewStrategy()
.withType("Docker")
.withNewDockerStrategy()
.withNoCache(false)
.endDockerStrategy()
.endStrategy()
.withNewOutput()
.withNewTo()
.withKind("ImageStreamTag")
.withName(runID + ":latest")
.endTo()
.endOutput()
.endSpec()
.build();
config = getClientExt().buildConfigs().createOrReplace(config);
holder.addResource(config);
final Long lastBuildVersion = config.getStatus().getLastVersion();
BuildRequest br = new BuildRequestBuilder()
.withNewMetadata()
.withName(config.getMetadata().getName())
.withLabels(defaultLabels)
.endMetadata()
.build();
getClientExt().buildConfigs().inNamespace(namespace).withName(runID).instantiate(br);
Build build = ResourceUtil.waitForComplete(
getClientExt(),
getClientExt().builds().inNamespace(namespace)
.withName(String.format("%s-%d", config.getMetadata().getName(), (lastBuildVersion + 1)))
.get());
holder.addResource(build);
is = getClientExt().imageStreams().inNamespace(namespace).withName(is.getMetadata().getName()).get();
String imageRef = is.getStatus().getTags().get(0).getItems().get(0).getDockerImageReference();
template.resolve(ref, imageRef);
Pod service = createStartablePod(template, defaultLabels);
holder.setPod(service);
} catch (Exception e) {
holder.setException(e);
}
}
return holder;
}
private Pod createStartablePod(Template template, Map defaultLabels) {
Map allLabels = new HashMap();
allLabels.putAll(defaultLabels);
allLabels.putAll(template.getTarget().getMetadata().getLabels());
Pod service = new PodBuilder()
.withNewMetadataLike(template.getTarget().getMetadata())
.withLabels(allLabels)
.endMetadata()
.withNewSpecLike(template.getTarget().getSpec())
.endSpec()
.build();
return service;
}
public Pod createAndWait(Pod resource) throws Exception {
return waitForStart(
getClient(),
getClient().pods().inNamespace(namespace).create(resource));
}
public Service create(Service resource) throws Exception {
return (Service) getClient().services().inNamespace(namespace).create(resource);
}
public void destroy(Pod resource) throws Exception {
getClient().pods().inNamespace(namespace).withName(resource.getMetadata().getName()).delete();
}
public void destroy(Service resource) throws Exception {
getClient().services().inNamespace(namespace).withName(resource.getMetadata().getName()).delete();
}
public Pod update(Pod resource) throws Exception {
return getClient().resource(resource).createOrReplace();
}
public void shutdown() throws Exception {
if (!keepAliveGitServer) {
gitserver.shutdown();
}
}
public NamespacedOpenShiftClient getClient() {
return kubernetes;
}
public io.fabric8.openshift.clnt.v2_5.OpenShiftClient getClientExt() {
return kubernetes;
}
private Map getDefaultLabels() {
Map labels = new HashMap();
labels.put("generatedby", "arquillian");
return labels;
}
public static class ResourceHolder {
public Pod pod;
public Set resources;
private Exception exception;
public ResourceHolder() {
this(null);
}
public ResourceHolder(Pod pod) {
this.pod = pod;
this.resources = new HashSet();
}
public Exception getException() {
return exception;
}
public void setException(Exception exception) {
this.exception = exception;
}
public void addResource(KubernetesResource resource) {
this.resources.add(resource);
}
public Set getResources() {
if (resources == null) {
return new HashSet();
}
return resources;
}
public Pod getPod() {
return pod;
}
public void setPod(Pod pod) {
this.pod = pod;
}
}
}