package io.cattle.platform.process.instance; import io.cattle.iaas.labels.service.LabelsService; import io.cattle.platform.agent.instance.dao.AgentInstanceDao; import io.cattle.platform.agent.instance.factory.AgentInstanceFactory; import io.cattle.platform.core.constants.AccountConstants; import io.cattle.platform.core.constants.InstanceConstants; import io.cattle.platform.core.model.Account; import io.cattle.platform.core.model.Instance; import io.cattle.platform.core.util.SystemLabels; import io.cattle.platform.engine.handler.ProcessPostListener; import io.cattle.platform.engine.process.ProcessInstance; import io.cattle.platform.engine.process.ProcessState; import io.cattle.platform.eventing.model.Event; import io.cattle.platform.eventing.model.EventVO; import io.cattle.platform.object.util.DataAccessor; import io.cattle.platform.process.common.handler.AgentBasedProcessLogic; import io.cattle.platform.util.exception.ExecutionException; import io.cattle.platform.util.type.CollectionUtils; import java.util.List; import java.util.Map; import javax.inject.Inject; public class K8sLabelsProviderProcessPostListener extends AgentBasedProcessLogic implements ProcessPostListener { @Inject AgentInstanceDao agentInstanceDao; @Inject AgentInstanceFactory agentInstanceFactory; @Inject LabelsService labelsService; @Override protected Object getAgentResource(ProcessState state, ProcessInstance process, Object dataResource) { Instance instance = getInstance(state); if (!isPod(instance)) { return false; } Long accountId = instance.getAccountId(); List<Long> agentIds = agentInstanceDao.getAgentProvider(SystemLabels.LABEL_AGENT_SERVICE_LABELS_PROVIDER, accountId); Long agentId = agentIds.size() == 0 ? null : agentIds.get(0); if ((instance instanceof Instance) && (agentIds.contains(instance.getAgentId()) || instance.getSystem())) { return null; } if (agentId == null) { if (k8sRequired(instance)) { throw new ExecutionException("Failed to find labels provider", instance); } else { return null; } } return agentId; } protected boolean k8sRequired(Instance instance) { Account account = objectManager.loadResource(Account.class, instance.getAccountId()); String orch = DataAccessor.fieldString(account, AccountConstants.FIELD_ORCHESTRATION); return AccountConstants.ORC_KUBERNETES_DISPLAY.equals(orch); } protected boolean isPod(Instance instance) { Map<String, Object> labels = DataAccessor.fieldMap(instance, InstanceConstants.FIELD_LABELS); Object namespace = labels.get(K8sPreInstanceCreate.POD_NAMESPACE); Object name = labels.get(K8sPreInstanceCreate.POD_NAME); Object containerName = labels.get(K8sPreInstanceCreate.CONTAINER_NAME); if (namespace == null || name == null) { return false; } return K8sPreInstanceCreate.POD.equals(containerName); } protected Instance getInstance(ProcessState state) { Object instance = state.getResource(); if (!(instance instanceof Instance)) { instance = getObjectByRelationship("instance", instance); } return (Instance)instance; } @Override protected void preProcessEvent(EventVO<?> event, ProcessState state, ProcessInstance process, Object eventResource, Object dataResource, Object agentResource) { Map<String, Object> data = CollectionUtils.toMap(event.getData()); if (!data.containsKey("instance")) { Object instanceData = CollectionUtils.getNestedValue(data, "instanceHostMap", "instance"); data.put("instance", instanceData); } super.preProcessEvent(event, state, process, eventResource, dataResource, agentResource); } @Override protected void postProcessEvent(EventVO<?> event, Event reply, ProcessState state, ProcessInstance process, Object eventResource, Object dataResource, Object agentResource) { Map<String, String> labels = CollectionUtils.toMap(CollectionUtils.getNestedValue(reply.getData(), "instance", "+data", "+fields", "+labels")); if (labels.size() == 0) { labels = CollectionUtils.toMap(CollectionUtils.getNestedValue(reply.getData(), "instanceHostMap", "instance", "+data", "+fields", "+labels")); } else { CollectionUtils.setNestedValue(CollectionUtils.toMap(reply.getData()), labels, "instanceHostMap", "instance", "+data", "+fields", "+labels"); } Instance instance = getInstance(state); if (labels.size() == 0) { throw new ExecutionException("Failed to find labels for POD", instance); } for (Map.Entry<String, String>label : labels.entrySet()) { labelsService.createContainerLabel(instance.getAccountId(), instance.getId(), label.getKey(), label.getValue()); } } }