Skip to content

Commit

Permalink
Make compatible with shinyproxy-operator
Browse files Browse the repository at this point in the history
 - add label with instance-id (i.e. hash of config file)
 - add label that it is a proxied app
  • Loading branch information
LEDfan committed Sep 22, 2020
1 parent 55e24ab commit 0c7baa8
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
@SpringBootApplication
@ComponentScan("eu.openanalytics")
public class ContainerProxyApplication {
private static final String CONFIG_FILENAME = "application.yml";
private static final String CONFIG_DEMO_PROFILE = "demo";
public static final String CONFIG_FILENAME = "application.yml";
public static final String CONFIG_DEMO_PROFILE = "demo";

@Inject
private Environment environment;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@
package eu.openanalytics.containerproxy.backend.kubernetes;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -40,8 +44,16 @@

import org.apache.commons.io.IOUtils;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;

import eu.openanalytics.containerproxy.ContainerProxyApplication;
import eu.openanalytics.containerproxy.ContainerProxyException;
import eu.openanalytics.containerproxy.backend.AbstractContainerBackend;
import eu.openanalytics.containerproxy.model.runtime.Container;
Expand Down Expand Up @@ -97,6 +109,10 @@ public class KubernetesBackend extends AbstractContainerBackend {

private static final String SECRET_KEY_REF = "secretKeyRef";

private static final String LABEL_PROXIED_APP = "openanalytics.eu/containerproxy-proxied-app";
private static final String LABEL_INSTANCE = "openanalytics.eu/sp-instance";


@Inject
private PodPatcher podPatcher;

Expand All @@ -122,6 +138,11 @@ public void initialize() throws ContainerProxyException {
}

kubeClient = new DefaultKubernetesClient(configBuilder.build());
try {
log.info("Hash of config is: " + getInstanceId());
} catch(Exception e) {
e.printStackTrace();
}
}

public void initialize(KubernetesClient client) {
Expand Down Expand Up @@ -222,7 +243,9 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
.withName("sp-pod-" + container.getId())
.addToLabels(spec.getLabels())
.addToLabels("app", container.getId())
.endMetadata();
.addToLabels(LABEL_INSTANCE, getInstanceId())
.addToLabels(LABEL_PROXIED_APP, "true")
.endMetadata();

PodSpec podSpec = new PodSpec();
podSpec.setContainers(Collections.singletonList(containerBuilder.build()));
Expand Down Expand Up @@ -262,6 +285,8 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
.withKind("Service")
.withNewMetadata()
.withName("sp-service-" + container.getId())
.addToLabels(LABEL_INSTANCE, getInstanceId())
.addToLabels(LABEL_PROXIED_APP, "true")
.endMetadata()
.withNewSpec()
.addToSelector("app", container.getId())
Expand Down Expand Up @@ -406,6 +431,42 @@ public BiConsumer<OutputStream, OutputStream> getOutputAttacher(Proxy proxy) {
protected String getPropertyPrefix() {
return PROPERTY_PREFIX;
}

private String instanceId = null;

/**
* Calculates a hash of the config file (i.e. application.yaml).
*/
private String getInstanceId() throws JsonParseException, JsonMappingException, IOException, NoSuchAlgorithmException {
if (instanceId != null) {
return instanceId;
}

/**
* We need a hash of some "canonical" version of the config file.
* The hash should not change when e.g. comments are added to the file.
* Therefore we read the application.yml file into an Object and then
* dump it again into YAML. We also sort the keys of maps and properties so that
* the order does not matter for the resulting hash.
*/
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

File file = Paths.get(ContainerProxyApplication.CONFIG_FILENAME).toFile();
if (!file.exists()) {
file = Paths.get(ContainerProxyApplication.CONFIG_DEMO_PROFILE).toFile();
}

Object parsedConfig = objectMapper.readValue(file, Object.class);
String canonicalConfigFile = objectMapper.writeValueAsString(parsedConfig);

MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.reset();
digest.update(canonicalConfigFile.getBytes(Charsets.UTF_8));
instanceId = String.format("%040x", new BigInteger(1, digest.digest()));
return instanceId;
}


}

0 comments on commit 0c7baa8

Please sign in to comment.