TunnelServerImplK8s.java

package jasper.component.channel;

import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import jasper.component.ConfigCache;
import jasper.config.Props;
import jasper.repository.UserRepository;
import jasper.service.dto.UserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Profile;
import org.springframework.context.event.EventListener;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

@Profile("kubernetes")
@Component
public class TunnelServerImplK8s implements TunnelServer {
	private static final Logger logger = LoggerFactory.getLogger(TunnelServerImplK8s.class);

	@Autowired
	Props props;

	@Autowired
	UserRepository userRepository;

	@Autowired
	ConfigCache configs;

	@EventListener(ApplicationReadyEvent.class)
	public void init() {
		configs.rootUpdate(root -> {
			if (root.getSshOrigins().isEmpty()) return;
			generateHostKey();
			generateConfig();
		});
	}

	@ServiceActivator(inputChannel = "userRxChannel")
	public void handleUserUpdate(Message<UserDto> message) {
		if (configs.root().getSshOrigins().isEmpty()) return;
		var user = message.getPayload();
		if ("+user".equals(user.getTag()) && props.getLocalOrigin().equals(user.getOrigin())) {
			generateHostKey();
		}
		if (configs.root().ssh(user.getOrigin())) {
			generateConfig();
		}
	}

	public void generateHostKey() {
		logger.info("Generating new host_key");
		var hostKey = "";
		if (configs.user() == null || configs.user().getKey() != null) {
			hostKey = new String(configs.user().getKey());
		}
		try (var client = new DefaultKubernetesClient()) {
			client.secrets()
				.inNamespace(props.getSshConfigNamespace())
				.resource(new SecretBuilder()
					.withNewMetadata()
					.withName(props.getSshSecretName())
					.and()
					.addToStringData("host_key", hostKey)
					.build())
				.serverSideApply();
		}
	}

	public void generateConfig() {
		logger.info("Generating new authorized_keys");
		var result = authorizedKeys(configs.root().getSshOrigins(), userRepository);
		try (var client = new DefaultKubernetesClient()) {
			client.configMaps()
				.inNamespace(props.getSshConfigNamespace())
				.resource(new ConfigMapBuilder()
					.withNewMetadata()
						.withName(props.getSshConfigMapName())
					.and()
					.addToData("authorized_keys", result.toString())
					.build())
				.serverSideApply();
		}
	}

}