All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ar4k.agent.helper.ConfigHelper Maven / Gradle / Ivy

There is a newer version: 0.9.1014
Show newest version
package org.ar4k.agent.helper;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Collection;
import java.util.HashSet;
import java.util.Random;
import java.util.UUID;

import javax.crypto.NoSuchPaddingException;

import org.ar4k.agent.config.EdgeConfig;
import org.ar4k.agent.config.json.PotInterfaceAdapter;
import org.ar4k.agent.core.Homunculus;
import org.ar4k.agent.core.interfaces.ConfigSeed;
import org.ar4k.agent.core.interfaces.ServiceConfig;
import org.ar4k.agent.logger.EdgeLogger;
import org.ar4k.agent.logger.EdgeStaticLoggerBinder;
import org.bouncycastle.cms.CMSAlgorithm;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.KeyTransRecipientInformation;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.OutputEncryptor;
import org.yaml.snakeyaml.Yaml;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.common.base.Splitter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ConfigHelper {

	private static final EdgeLogger logger = EdgeStaticLoggerBinder.getClassLogger(ConfigHelper.class);

	public static final String NETTY_CTX_CLIENT = "net-ctx-c";

	public static final String NETTY_CTX_SERVER = "net-ctx-s";
	public static final String KOPS_BINARY_PATH = "~/bin/kops";
	public static final String BASE_BASH_CMD = "/bin/bash -l";
	public static final String LATEST_KOPS_URL = "https://api.github.com/repos/kubernetes/kops/releases/latest";
	public static final String KOPS_URL = "https://github.com/kubernetes/kops/releases/download/$version/kops-linux-amd64";
	public static final String MINIKUBE_BINARY_PATH = "~/bin/minikube";
	public static final String MINIKUBE_URL = "https://storage.googleapis.com/minikube/releases/v1.1.1/minikube-linux-amd64";
	public static final String HELM_TGZ_PATH = "~/bin/helm.tgz";
	public static final String HELM_COMPRESSED_URL = "https://get.helm.sh/helm-v2.14.1-linux-amd64.tar.gz";
	public static final String HELM_DIRECTORY_PATH = "~/bin";
	public static final String LATEST_KUBECTL_URL = "https://storage.googleapis.com/kubernetes-release/release/stable.txt";
	public static final String KUBECTL_BINARY_PATH = "~/bin/kubectl";
	public static final String KUBECTL_URL = "https://storage.googleapis.com/kubernetes-release/release/$version/bin/linux/amd64/kubectl";
	public static final String KUBEFLOW_TGZ_PATH = "~/bin/kubeflow.tgz";
	public static final String KUBEFLOW_COMPRESSED_URL = "https://github.com/kubeflow/kubeflow/archive/v0.4.1.tar.gz";
	public static final String KUBEFLOW_DIRECTORY_PATH = "~/bin";
	public static final String KSONNET_TGZ_PATH = "~/bin/ksonnet.tgz";
	public static final String KSONNET_COMPRESSED_URL = "https://github.com/ksonnet/ksonnet/releases/download/v0.13.1/ks_0.13.1_linux_amd64.tar.gz";
	public static final String KSONNET_DIRECTORY_PATH = "~/bin";
	public static final String KUBECONFIG = "~/.kube/config";
	public static final String SHELL_INTERACTIVE_START = "~/.ssty_noecho";
	// default value
	public static final String organization = "Rossonet";

	public static final String unit = "Ar4k";
	public static final String locality = "Imola";
	public static final String state = "Bologna";
	public static final String country = "IT";
	public static final String uri = "https://www.rossonet.net";
	public static final String dns = NetworkHelper.getHostname();
	public static final String ip = "127.0.0.1";

	public static final int defaulBeaconSignvalidity = 100;

	private static final String TILDE = "~";

	private static final String DEFAULT_PATH = "!";

	public static final String USER_HOME = System.getProperty("user.home");

	private ConfigHelper() {
		throw new UnsupportedOperationException("Just for static usage");
	}

	public static int countWorkingStringSplittedByComma(String input, boolean isFile) {
		return resolveWorkingString(input, isFile).split(",").length;
	}

	public static String createRandomRegistryId() {
		final StringBuilder val = new StringBuilder();
		val.append("AR");
		// char (1), random A-Z
		final int ranChar = 65 + (new Random()).nextInt(90 - 65);
		final char ch = (char) ranChar;
		val.append(ch);
		// numbers (6), random 0-9
		final Random r = new Random();
		final int numbers = 100000 + (int) (r.nextFloat() * 899900);
		val.append(String.valueOf(numbers));
		val.append("-");
		// char or numbers (5), random 0-9 A-Z
		for (int i = 0; i < 6;) {
			final int ranAny = 48 + (new Random()).nextInt(90 - 65);
			if (!(57 < ranAny && ranAny <= 65)) {
				final char c = (char) ranAny;
				val.append(c);
				i++;
			}
		}
		return val.toString();
	}

	public static byte[] decryptData(byte[] encryptedData, PrivateKey decryptionKey) throws CMSException {
		final byte[] decryptedData = null;
		if (null != encryptedData && null != decryptionKey) {
			final CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData);
			final Collection recipients = envelopedData.getRecipientInfos().getRecipients();
			final KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recipients.iterator()
					.next();
			final JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(decryptionKey);
			return recipientInfo.getContent(recipient);
		}
		return decryptedData;
	}

	public static byte[] encryptData(byte[] data, X509Certificate encryptionCertificate)
			throws CertificateEncodingException, CMSException, IOException {
		byte[] encryptedData = null;
		if (null != data && null != encryptionCertificate) {
			final CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator();
			final JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(
					encryptionCertificate);
			cmsEnvelopedDataGenerator.addRecipientInfoGenerator(jceKey);
			final CMSTypedData msg = new CMSProcessableByteArray(data);
			final OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC)
					.setProvider(new BouncyCastleProvider()).build();
			final CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor);
			encryptedData = cmsEnvelopedData.getEncoded();
		}
		return encryptedData;
	}

	public static ConfigSeed fromBase64(String base64Config) throws IOException, ClassNotFoundException {
		final byte[] data = Base64.getDecoder().decode(base64Config);
		final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
		final ConfigSeed rit = (ConfigSeed) ois.readObject();
		ois.close();
		return rit;
	}

	public static ConfigSeed fromBase64Crypto(String base64RsaConfig, String aliasKey)
			throws ClassNotFoundException, IOException, CMSException, NoSuchAlgorithmException, NoSuchPaddingException {
		final PrivateKey key = Homunculus.getApplicationContext().getBean(Homunculus.class).getMyIdentityKeystore()
				.getPrivateKey(aliasKey);
		return fromBase64(new String(decryptData(Base64.getDecoder().decode(base64RsaConfig), key)));
	}

	public static ConfigSeed fromJson(String jsonConfig, Class targetClass) {
		final GsonBuilder builder = new GsonBuilder();
		builder.registerTypeAdapter(ServiceConfig.class, new PotInterfaceAdapter());
		final Gson gson = builder.setPrettyPrinting().create();
		return gson.fromJson(jsonConfig, targetClass);
	}

	public static EdgeConfig fromYaml(String yamlConfig) {
		final Yaml yaml = new Yaml();
		return yaml.load(yamlConfig);
	}

	public static EdgeConfig fromXml(String xmlConfig) throws JsonMappingException, JsonProcessingException {
		XmlMapper xmlMapper = new XmlMapper();
		return xmlMapper.readValue(xmlConfig, EdgeConfig.class);
	}

	public static String generateNewUniqueName(String nameInParameters, String fileNameInParameters) {
		String result = null;
		if (fileNameInParameters != null && !fileNameInParameters.isEmpty()) {
			final File fileUniqueName = new File(ConfigHelper.resolveWorkingString(fileNameInParameters, true));
			if (fileUniqueName.exists() && fileUniqueName.canRead()) {
				try {
					result = Files.readAllLines(fileUniqueName.toPath()).get(0);
				} catch (final IOException e) {
					logger.logException("uniqueName file " + fileUniqueName + " exception", e);
				}
			} else {
				logger.info("uniqueName file " + fileUniqueName + " not exists or is not readable");
			}
		} else {
			if (nameInParameters != null && !nameInParameters.isEmpty()) {
				result = ConfigHelper.resolveWorkingString(nameInParameters, false);
			} else {
				try {
					result = InetAddress.getLocalHost().getHostName() + "_"
							+ UUID.randomUUID().toString().replaceAll("-", "");
				} catch (final UnknownHostException e) {
					logger.info("no hostname found...");
					result = "agent_" + UUID.randomUUID().toString().replaceAll("-", "");
				}
			}
		}
		return result;
	}

	public static String resolveWorkingString(String input, boolean isFile) {
		String resultString = null;
		if (isFile) {
			resultString = input.replace(DEFAULT_PATH,
					Homunculus.getApplicationContext().getBean(Homunculus.class).getStarterProperties().getConfPath())
					.replace(TILDE, USER_HOME);
		} else {
			resultString = input;
		}
		return resultString.replace("{hostname}", dns).replace("{env-check}", "test-conf")
				.replace("{env-check}", "test-conf").replace("{mac}", NetworkHelper.getFirstMacAddressAsString());
	}

	public static String resolveWorkingStringSplittedByComma(String input, boolean isFile, int pos) {
		return resolveWorkingString(input, isFile).split(",")[pos];
	}

	public static String toBase64(Object configObject) throws IOException {
		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
		final ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(configObject);
		oos.close();
		return Base64.getEncoder().encodeToString(baos.toByteArray());
	}

	public static String toBase64Crypto(Object configObject, String aliasKey)
			throws CertificateEncodingException, UnsupportedEncodingException, CMSException, IOException {
		final X509Certificate certificate = Homunculus.getApplicationContext().getBean(Homunculus.class)
				.getMyIdentityKeystore().getClientCertificate(aliasKey);
		return Base64.getEncoder().encodeToString(encryptData(toBase64(configObject).getBytes("UTF-8"), certificate));
	}

	public static String toBase64ForDns(String name, Object configObject) throws IOException {
		final Iterable chunks = Splitter.fixedLength(254).split(toBase64(configObject));
		final StringBuilder result = new StringBuilder();
		int counter = 0;
		for (final String s : chunks) {
			result.append(name + "-" + String.valueOf(counter) + "\tIN\tTXT\t" + '"' + s + '"' + "\n");
			counter++;
		}
		result.append(name + "-max" + "\tIN\tTXT\t" + '"' + String.valueOf(counter) + '"' + "\n");
		return result.toString();
	}

	public static String toBase64ForDnsCrypto(String name, Object configObject, String aliasKey)
			throws IOException, CertificateEncodingException, CMSException {
		final Iterable chunks = Splitter.fixedLength(254).split(toBase64Crypto(configObject, aliasKey));
		final StringBuilder result = new StringBuilder();
		int counter = 0;
		for (final String s : chunks) {
			result.append(name + "-" + String.valueOf(counter) + "\tIN\tTXT\t" + '"' + s + '"' + "\n");
			counter++;
		}
		result.append(name + "-max" + "\tIN\tTXT\t" + '"' + String.valueOf(counter) + '"' + "\n");
		return result.toString();
	}

	public static String toJson(ConfigSeed configObject) {
		final GsonBuilder builder = new GsonBuilder();
		builder.registerTypeAdapter(ServiceConfig.class, new PotInterfaceAdapter());
		final Gson gson = builder.setPrettyPrinting().create();
		return gson.toJson(configObject);
	}

	public static String toYaml(ConfigSeed workingConfig) {
		final Yaml yaml = new Yaml();
		return yaml.dump(workingConfig);
	}

	public static String toXml(ConfigSeed workingConfig) throws JsonProcessingException {
		XmlMapper xmlMapper = new XmlMapper();
		return xmlMapper.writeValueAsString(workingConfig);
	}

	public static Collection mergeTags(Collection additionalData, Collection tags) {
		HashSet merge = new HashSet<>();
		merge.addAll(tags);
		merge.addAll(additionalData);
		return merge;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy