Skip to content

Commit 48da846

Browse files
committed
Merge pull request 'Store all runtime info in proxy.runtimeValues' (#45) from feature/24996 into develop
2 parents bc77bd6 + 9ef8cbc commit 48da846

31 files changed

Lines changed: 1024 additions & 153 deletions

src/main/java/eu/openanalytics/containerproxy/ContainerProxyApplication.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public static void main(String[] args) {
9292
}
9393
}
9494

95+
9596
@PostConstruct
9697
public void init() {
9798
if (environment.getProperty("server.use-forward-headers") != null) {
@@ -183,7 +184,7 @@ public HttpSessionEventPublisher httpSessionEventPublisher() {
183184
return new HttpSessionEventPublisher();
184185
}
185186

186-
private static void setDefaultProperties(SpringApplication app) {
187+
public static Properties getDefaultProperties() {
187188
Properties properties = new Properties();
188189

189190
// use in-memory session storage by default. Can be overwritten in application.yml
@@ -230,7 +231,11 @@ private static void setDefaultProperties(SpringApplication app) {
230231

231232
// ====================
232233

233-
app.setDefaultProperties(properties);
234+
return properties;
235+
}
236+
237+
private static void setDefaultProperties(SpringApplication app) {
238+
app.setDefaultProperties(getDefaultProperties());
234239
}
235240

236241
}

src/main/java/eu/openanalytics/containerproxy/auth/IAuthenticationBackend.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020
*/
2121
package eu.openanalytics.containerproxy.auth;
2222

23-
import java.util.List;
23+
import java.util.Map;
2424

2525
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
2626
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
27-
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
2827
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.AuthorizedUrl;
2928

3029
import eu.openanalytics.containerproxy.model.spec.ContainerSpec;
@@ -68,7 +67,7 @@ public default void customizeContainer(ContainerSpec spec) {
6867
// Default: do nothing.
6968
}
7069

71-
public default void customizeContainerEnv(List<String> env) {
70+
public default void customizeContainerEnv(Map<String, String> env) {
7271
// Default: do nothing.
7372
}
7473

src/main/java/eu/openanalytics/containerproxy/auth/impl/KerberosAuthenticationBackend.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.ArrayList;
2525
import java.util.Collections;
2626
import java.util.List;
27+
import java.util.Map;
2728

2829
import javax.inject.Inject;
2930

@@ -157,10 +158,10 @@ public void customizeContainer(ContainerSpec spec) {
157158
}
158159

159160
@Override
160-
public void customizeContainerEnv(List<String> env) {
161+
public void customizeContainerEnv(Map<String, String> env) {
161162
String principal = getCurrentPrincipal();
162-
env.add("REMOTE_USER=" + principal);
163-
env.add("KRB5CCNAME=FILE:/tmp/kerberos/ccache");
163+
env.put("REMOTE_USER", principal);
164+
env.put("KRB5CCNAME", "FILE:/tmp/kerberos/ccache");
164165
}
165166

166167
private String getCurrentPrincipal() {

src/main/java/eu/openanalytics/containerproxy/auth/impl/OpenIDAuthenticationBackend.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,16 @@ public String getLogoutSuccessURL() {
139139
}
140140

141141
@Override
142-
public void customizeContainerEnv(List<String> env) {
142+
public void customizeContainerEnv(Map<String, String> env) {
143143
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
144144
if (auth == null) return;
145145

146146
OidcUser user = (OidcUser) auth.getPrincipal();
147147
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
148148
OAuth2AuthorizedClient client = oAuth2AuthorizedClientRepository.loadAuthorizedClient(REG_ID, auth, request);
149149
if (client == null || client.getAccessToken() == null) return;
150-
151-
env.add(ENV_TOKEN_NAME + "=" + client.getAccessToken().getTokenValue());
150+
151+
env.put(ENV_TOKEN_NAME, client.getAccessToken().getTokenValue());
152152
}
153153

154154
protected ClientRegistrationRepository createClientRepo() {

src/main/java/eu/openanalytics/containerproxy/backend/AbstractContainerBackend.java

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@
3333
import eu.openanalytics.containerproxy.model.runtime.Container;
3434
import eu.openanalytics.containerproxy.model.runtime.Proxy;
3535
import eu.openanalytics.containerproxy.model.runtime.ProxyStatus;
36+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.CreatedTimestampKey;
37+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.InstanceIdKey;
38+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.ProxiedAppKey;
39+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.ProxyIdKey;
40+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.ProxySpecIdKey;
41+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.RealmIdKey;
42+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.RuntimeValue;
43+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.UserGroupsKey;
44+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.UserIdKey;
3645
import eu.openanalytics.containerproxy.model.spec.ContainerSpec;
3746
import eu.openanalytics.containerproxy.service.UserService;
3847
import eu.openanalytics.containerproxy.spec.expression.ExpressionAwareContainerSpec;
@@ -57,7 +66,6 @@
5766
import java.util.function.BiConsumer;
5867
import java.util.regex.Matcher;
5968
import java.util.regex.Pattern;
60-
import java.util.stream.Collectors;
6169

6270
public abstract class AbstractContainerBackend implements IContainerBackend {
6371

@@ -69,20 +77,6 @@ public abstract class AbstractContainerBackend implements IContainerBackend {
6977

7078
protected static final String DEFAULT_TARGET_PROTOCOL = "http";
7179

72-
//TODO rename vars?
73-
protected static final String ENV_VAR_USER_NAME = "SHINYPROXY_USERNAME";
74-
protected static final String ENV_VAR_USER_GROUPS = "SHINYPROXY_USERGROUPS";
75-
protected static final String ENV_VAR_REALM_ID = "SHINYPROXY_REALM_ID";
76-
77-
protected static final String RUNTIME_LABEL_PROXY_ID = "openanalytics.eu/sp-proxy-id";
78-
protected static final String RUNTIME_LABEL_USER_ID = "openanalytics.eu/sp-user-id";
79-
protected static final String RUNTIME_LABEL_USER_GROUPS = "openanalytics.eu/sp-user-groups";
80-
protected static final String RUNTIME_LABEL_REALM_ID = "openanalytics.eu/sp-realm-id";
81-
protected static final String RUNTIME_LABEL_PROXY_SPEC_ID = "openanalytics.eu/sp-spec-id";
82-
protected static final String RUNTIME_LABEL_CREATED_TIMESTAMP = "openanalytics.eu/sp-proxy-created-timestamp";
83-
protected static final String RUNTIME_LABEL_PROXIED_APP = "openanalytics.eu/sp-proxied-app";
84-
protected static final String RUNTIME_LABEL_INSTANCE = "openanalytics.eu/sp-instance";
85-
8680
protected final Logger log = LogManager.getLogger(getClass());
8781

8882
private boolean useInternalNetwork;
@@ -131,6 +125,7 @@ public SuccessOrFailure<Proxy> startProxy(Proxy proxy) throws ContainerProxyExce
131125
proxy.setId(UUID.randomUUID().toString());
132126
proxy.setStatus(ProxyStatus.Starting);
133127
proxy.setCreatedTimestamp(System.currentTimeMillis());
128+
setRuntimeValues(proxy);
134129

135130
try {
136131
doStartProxy(proxy);
@@ -161,20 +156,6 @@ protected void doStartProxy(Proxy proxy) throws Exception {
161156
for (ContainerSpec spec: proxy.getSpec().getContainerSpecs()) {
162157
if (authBackend != null) authBackend.customizeContainer(spec);
163158

164-
// add labels need for App Recovery and maintenance
165-
spec.addRuntimeLabel(RUNTIME_LABEL_PROXIED_APP, true, "true");
166-
spec.addRuntimeLabel(RUNTIME_LABEL_INSTANCE, true, instanceId);
167-
168-
spec.addRuntimeLabel(RUNTIME_LABEL_PROXY_ID, false, proxy.getId());
169-
spec.addRuntimeLabel(RUNTIME_LABEL_PROXY_SPEC_ID, false, proxy.getSpec().getId());
170-
if (realmId != null) {
171-
spec.addRuntimeLabel(RUNTIME_LABEL_REALM_ID, false, realmId);
172-
}
173-
spec.addRuntimeLabel(RUNTIME_LABEL_USER_ID, false, proxy.getUserId());
174-
String[] groups = userService.getGroups(userService.getCurrentAuth());
175-
spec.addRuntimeLabel(RUNTIME_LABEL_USER_GROUPS, false, String.join(",", groups));
176-
spec.addRuntimeLabel(RUNTIME_LABEL_CREATED_TIMESTAMP, false, String.valueOf(proxy.getCreatedTimestamp()));
177-
178159
ExpressionAwareContainerSpec eSpec = new ExpressionAwareContainerSpec(spec,
179160
proxy,
180161
expressionResolver,
@@ -238,35 +219,31 @@ protected Long memoryToBytes(String memory) {
238219
}
239220
return mem;
240221
}
241-
242-
protected List<String> buildEnv(ContainerSpec containerSpec, Proxy proxy) throws IOException {
243-
List<String> env = new ArrayList<>();
244-
env.add(String.format("%s=%s", ENV_VAR_USER_NAME, proxy.getUserId()));
245-
246-
String[] groups = userService.getGroups(userService.getCurrentAuth());
247-
env.add(String.format("%s=%s", ENV_VAR_USER_GROUPS, Arrays.stream(groups).collect(Collectors.joining(","))));
248-
249-
String realmId = environment.getProperty("proxy.realm-id");
250-
if (realmId != null) {
251-
env.add(String.format("%s=%s", ENV_VAR_REALM_ID, realmId));
222+
223+
protected Map<String, String> buildEnv(ContainerSpec containerSpec, Proxy proxy) throws IOException {
224+
Map<String, String> env = new HashMap<>();
225+
226+
for (RuntimeValue runtimeValue : proxy.getRuntimeValues().values()) {
227+
if (runtimeValue.getKey().getIncludeAsEnvironmentVariable()) {
228+
env.put(runtimeValue.getKey().getKeyAsEnvVar(), runtimeValue.getValue());
229+
}
252230
}
253231

254232
String envFile = containerSpec.getEnvFile();
255233
if (envFile != null && Files.isRegularFile(Paths.get(envFile))) {
256234
Properties envProps = new Properties();
257235
envProps.load(new FileInputStream(envFile));
258236
for (Object key: envProps.keySet()) {
259-
env.add(String.format("%s=%s", key, envProps.get(key)));
237+
env.put(key.toString(), envProps.get(key).toString());
260238
}
261239
}
262240

263241
if (containerSpec.getEnv() != null) {
264242
for (Map.Entry<String, String> entry : containerSpec.getEnv().entrySet()) {
265-
env.add(String.format("%s=%s", entry.getKey(), entry.getValue()));
243+
env.put(entry.getKey(), entry.getValue());
266244
}
267245
}
268246

269-
// Allow the authentication backend to add values to the environment, if needed.
270247
if (authBackend != null) authBackend.customizeContainerEnv(env);
271248

272249
return env;
@@ -352,4 +329,21 @@ public static String computeTargetPath(String targetPath) {
352329

353330
return targetPath;
354331
}
332+
333+
private void setRuntimeValues(Proxy proxy) {
334+
proxy.addRuntimeValue(new RuntimeValue(ProxiedAppKey.inst, "true"));
335+
proxy.addRuntimeValue(new RuntimeValue(ProxyIdKey.inst, proxy.getId()));
336+
proxy.addRuntimeValue(new RuntimeValue(InstanceIdKey.inst, instanceId));
337+
proxy.addRuntimeValue(new RuntimeValue(ProxySpecIdKey.inst, proxy.getSpec().getId()));
338+
339+
if (realmId != null) {
340+
proxy.addRuntimeValue(new RuntimeValue(RealmIdKey.inst, realmId));
341+
}
342+
343+
proxy.addRuntimeValue(new RuntimeValue(UserIdKey.inst, proxy.getUserId()));
344+
String[] groups = userService.getGroups(userService.getCurrentAuth());
345+
proxy.addRuntimeValue(new RuntimeValue(UserGroupsKey.inst, String.join(",", groups)));
346+
proxy.addRuntimeValue(new RuntimeValue(CreatedTimestampKey.inst, Long.toString(proxy.getCreatedTimestamp())));
347+
}
348+
355349
}

src/main/java/eu/openanalytics/containerproxy/backend/docker/AbstractDockerBackend.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import java.io.IOException;
2424
import java.io.OutputStream;
2525
import java.nio.file.Paths;
26+
import java.util.ArrayList;
27+
import java.util.List;
28+
import java.util.Map;
2629
import java.util.function.BiConsumer;
2730

2831
import com.spotify.docker.client.DefaultDockerClient;
@@ -108,4 +111,14 @@ protected Container getPrimaryContainer(Proxy proxy) {
108111
}
109112

110113

114+
protected List<String> convertEnv(Map<String, String> env) {
115+
List<String> res = new ArrayList<>();
116+
117+
for (Map.Entry<String, String> envVar : env.entrySet()) {
118+
res.add(String.format("%s=%s", envVar.getKey(), envVar.getValue()));
119+
}
120+
121+
return res;
122+
}
123+
111124
}

src/main/java/eu/openanalytics/containerproxy/backend/docker/DockerEngineBackend.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
import eu.openanalytics.containerproxy.model.runtime.Container;
4040
import eu.openanalytics.containerproxy.model.runtime.Proxy;
41+
import eu.openanalytics.containerproxy.model.runtime.runtimevalues.RuntimeValue;
4142
import eu.openanalytics.containerproxy.model.spec.ContainerSpec;
4243

4344
public class DockerEngineBackend extends AbstractDockerBackend {
@@ -74,15 +75,20 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
7475
hostConfigBuilder.privileged(isPrivileged() || spec.isPrivileged());
7576

7677
Map<String, String> labels = spec.getLabels();
77-
spec.getRuntimeLabels().forEach((key, value) -> labels.put(key, value.getSecond()));
78+
79+
for (RuntimeValue runtimeValue : proxy.getRuntimeValues().values()) {
80+
if (runtimeValue.getKey().getIncludeAsLabel() || runtimeValue.getKey().getIncludeAsAnnotation()) {
81+
labels.put(runtimeValue.getKey().getKeyAsLabel(), runtimeValue.getValue());
82+
}
83+
}
7884

7985
ContainerConfig containerConfig = ContainerConfig.builder()
8086
.hostConfig(hostConfigBuilder.build())
8187
.image(spec.getImage())
8288
.labels(labels)
8389
.exposedPorts(portBindings.keySet())
8490
.cmd(spec.getCmd())
85-
.env(buildEnv(spec, proxy))
91+
.env(convertEnv(buildEnv(spec, proxy)))
8692
.build();
8793
ContainerCreation containerCreation = dockerClient.createContainer(containerConfig);
8894

0 commit comments

Comments
 (0)