package com.lordofthejars.nosqlunit.vault; import com.bettercloud.vault.response.AuthResponse; import org.yaml.snakeyaml.Yaml; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; public class DataLoader { private static final String TOKENS = "tokens"; private VaultConnection vault; public DataLoader(VaultConnection vault) { this.vault = vault; } public void load(InputStream inputStream) { final Yaml yaml = new Yaml(); final Object load = yaml.load(inputStream); if (areOnlySecrets(load)) { final List<Map<String, Map<String, Object>>> secrets = (List) load; insertTokens(secrets); insertSecrets(secrets); } } private void insertSecrets(List<Map<String, Map<String, Object>>> secrets) { for (Map<String, Map<String, Object>> secret : secrets) { final Set<Map.Entry<String, Map<String, Object>>> entries = secret.entrySet(); for (Map.Entry<String, Map<String, Object>> entry : entries) { String backend = entry.getKey(); if (!TOKENS.equals(backend)) { vault.writeLogical(backend, entry.getValue()); } } } } private void insertTokens(List<Map<String, Map<String, Object>>> data) { final Optional<Map.Entry<String, Map<String, Object>>> tokens = data.stream() .flatMap(e -> e.entrySet().stream()) .filter(e -> TOKENS.equals(e.getKey())) .findFirst(); if (tokens.isPresent()) { final List<Map<String, Object>> tokenDefinitions = (List<Map<String, Object>>) tokens.get().getValue(); for (final Map<String, Object> tokenDefinition : tokenDefinitions) { final AuthResponse authResponse = vault.createToken() .displayName(asString(tokenDefinition, "displayName")) .meta(asMapOfStrings(tokenDefinition, "meta")) .noDefaultPolicy(asBoolean(tokenDefinition, "noDefaultPolicy")) .noParent(asBoolean(tokenDefinition, "noParent")) .policies(asListOfStrings(tokenDefinition, "policies")) .uuid(asString(tokenDefinition, "uuid")) .ttl(asInteger(tokenDefinition, "ttl")) .numUses(asLong(tokenDefinition, "numUses")) .create(); if (tokenDefinition.containsKey("secrets")) { List<Map<String, Map<String, Object>>> secrets = (List<Map<String, Map<String, Object>>>) tokenDefinition.get("secrets"); try { vault.updateToken(authResponse.getAuthClientToken()); insertSecrets(secrets); } finally { vault.reconnectToOriginal(); } } } } } private boolean areOnlySecrets(Object load) { return load instanceof List; } private Integer asInteger(Map<String, Object> elements, String key) { if (elements.containsKey(key)) { return (Integer) elements.get(key); } return null; } private Long asLong(Map<String, Object> elements, String key) { if (elements.containsKey(key)) { if (elements.get(key) instanceof Integer) { ((Integer) elements.get(key)).longValue(); } else { return (Long) elements.get(key); } } return null; } private Map<String, String> asMapOfStrings(Map<String, Object> elements, String key) { if (elements.containsKey(key)) { Map<String, Object> map = (Map<String, Object>) elements.get(key); return toStringMap(map); } return null; } private List<String> asListOfStrings(Map<String, Object> elements, String key) { if (elements.containsKey(key)) { return (List<String>) elements.get(key); } return null; } private Boolean asBoolean(Map<String, Object> elements, String key) { if (elements.containsKey(key)) { return (Boolean) elements.get(key); } return null; } private String asString(Map<String, Object> elements, String key) { if (elements.containsKey(key)) { return (String) elements.get(key); } return null; } private Map<String, String> toStringMap(Map<String, Object> elements) { return elements.entrySet() .stream() .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().toString())); } }