From 869466d43313e4f13c65a2abc027ef6fa1601bbd Mon Sep 17 00:00:00 2001 From: Albertin Loic Date: Wed, 18 Mar 2020 09:43:56 +0100 Subject: [PATCH 1/2] Multi-Locations: adapt modifiers --- .../modifier/KubernetesAdapterModifier.java | 165 +++++++++++------- .../KubernetesFinalTopologyModifier.java | 100 +++++------ .../KubernetesLocationTopologyModifier.java | 18 +- ...ubernetesAutomatchingTopologyModifier.java | 21 ++- 4 files changed, 172 insertions(+), 132 deletions(-) diff --git a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAdapterModifier.java b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAdapterModifier.java index f4f982d..4b68e3b 100644 --- a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAdapterModifier.java +++ b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAdapterModifier.java @@ -1,33 +1,60 @@ package org.alien4cloud.plugin.kubernetes.modifier; -import alien4cloud.component.repository.ArtifactRepositoryConstants; -import alien4cloud.paas.wf.TopologyContext; -import alien4cloud.paas.wf.WorkflowSimplifyService; -import alien4cloud.paas.wf.WorkflowsBuilderService; -import alien4cloud.paas.wf.validation.WorkflowValidator; -import alien4cloud.tosca.context.ToscaContext; -import alien4cloud.tosca.context.ToscaContextual; -import alien4cloud.tosca.parser.ToscaParser; -import alien4cloud.tosca.serializer.ToscaPropertySerializerUtils; -import alien4cloud.utils.CloneUtil; -import alien4cloud.utils.MapUtil; -import alien4cloud.utils.PropertyUtil; -import alien4cloud.utils.YamlParserUtil; +import static alien4cloud.utils.AlienUtils.safe; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.A4C_TYPES_APPLICATION_DOCKER_CONTAINER; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_BASE_RESOURCE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_DEPLOYMENT_RESOURCE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_ENDPOINT_RESOURCE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_JOB_RESOURCE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_SERVICE_RESOURCE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_SIMPLE_RESOURCE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.copyProperty; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.generateKubeName; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.getValue; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.portNameFromService; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.renameProperty; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.resolveDependency; +import static org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants.K8S_POLICIES_ANTI_AFFINITY_LABEL; +import static org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants.K8S_POLICIES_AUTO_SCALING; +import static org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants.K8S_POLICIES_NODE_AFFINITY_LABEL; +import static org.alien4cloud.tosca.utils.ToscaTypeUtils.isOfType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import javax.annotation.Resource; + import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import lombok.extern.java.Log; -import lombok.extern.slf4j.Slf4j; + import org.alien4cloud.alm.deployment.configuration.flow.FlowExecutionContext; import org.alien4cloud.alm.deployment.configuration.flow.TopologyModifierSupport; import org.alien4cloud.plugin.kubernetes.AbstractKubernetesModifier; import org.alien4cloud.plugin.kubernetes.modifier.helpers.AffinitiyHelper; import org.alien4cloud.plugin.kubernetes.modifier.helpers.AntiAffinityHelper; -import org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants; -import org.alien4cloud.tosca.model.CSARDependency; import org.alien4cloud.tosca.model.Csar; -import org.alien4cloud.tosca.model.definitions.*; -import org.alien4cloud.tosca.model.templates.*; +import org.alien4cloud.tosca.model.definitions.AbstractPropertyValue; +import org.alien4cloud.tosca.model.definitions.ComplexPropertyValue; +import org.alien4cloud.tosca.model.definitions.ConcatPropertyValue; +import org.alien4cloud.tosca.model.definitions.DeploymentArtifact; +import org.alien4cloud.tosca.model.definitions.FunctionPropertyValue; +import org.alien4cloud.tosca.model.definitions.ListPropertyValue; +import org.alien4cloud.tosca.model.definitions.Operation; +import org.alien4cloud.tosca.model.definitions.PropertyDefinition; +import org.alien4cloud.tosca.model.definitions.PropertyValue; +import org.alien4cloud.tosca.model.definitions.ScalarPropertyValue; +import org.alien4cloud.tosca.model.templates.Capability; +import org.alien4cloud.tosca.model.templates.NodeTemplate; +import org.alien4cloud.tosca.model.templates.PolicyTemplate; +import org.alien4cloud.tosca.model.templates.RelationshipTemplate; +import org.alien4cloud.tosca.model.templates.ServiceNodeTemplate; +import org.alien4cloud.tosca.model.templates.SubstitutionTarget; +import org.alien4cloud.tosca.model.templates.Topology; import org.alien4cloud.tosca.model.types.AbstractToscaType; import org.alien4cloud.tosca.model.types.CapabilityType; import org.alien4cloud.tosca.model.types.NodeType; @@ -35,22 +62,28 @@ import org.alien4cloud.tosca.normative.constants.NormativeCapabilityTypes; import org.alien4cloud.tosca.normative.constants.NormativeRelationshipConstants; import org.alien4cloud.tosca.normative.constants.ToscaFunctionConstants; -import org.alien4cloud.tosca.utils.*; +import org.alien4cloud.tosca.utils.FunctionEvaluator; +import org.alien4cloud.tosca.utils.FunctionEvaluatorContext; +import org.alien4cloud.tosca.utils.TopologyNavigationUtil; +import org.alien4cloud.tosca.utils.ToscaTypeUtils; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; -import javax.annotation.Resource; -import java.util.*; -import java.util.logging.Level; -import java.util.stream.Stream; - -import static alien4cloud.utils.AlienUtils.safe; -import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.*; -import static org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants.K8S_POLICIES_ANTI_AFFINITY_LABEL; -import static org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants.K8S_POLICIES_AUTO_SCALING; -import static org.alien4cloud.plugin.kubernetes.policies.KubePoliciesConstants.K8S_POLICIES_NODE_AFFINITY_LABEL; -import static org.alien4cloud.tosca.utils.ToscaTypeUtils.isOfType; +import alien4cloud.component.repository.ArtifactRepositoryConstants; +import alien4cloud.paas.wf.TopologyContext; +import alien4cloud.paas.wf.WorkflowSimplifyService; +import alien4cloud.paas.wf.WorkflowsBuilderService; +import alien4cloud.paas.wf.validation.WorkflowValidator; +import alien4cloud.tosca.context.ToscaContext; +import alien4cloud.tosca.context.ToscaContextual; +import alien4cloud.tosca.parser.ToscaParser; +import alien4cloud.tosca.serializer.ToscaPropertySerializerUtils; +import alien4cloud.utils.CloneUtil; +import alien4cloud.utils.MapUtil; +import alien4cloud.utils.PropertyUtil; +import alien4cloud.utils.YamlParserUtil; +import lombok.extern.slf4j.Slf4j; /** * Transform a K8S topology containing KubeContainers, KubeDeployments, KubeServices @@ -127,7 +160,7 @@ private void doProcess(KubernetesModifierContext context) { NodeTemplate kubeNSResourceNode = null; String namespace = null; AbstractPropertyValue nsConfigPV = null; - Set kubeNSNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_KUBE_NAMESPACE, false); + Set kubeNSNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_KUBE_NAMESPACE, false); if (kubeNSNodes != null && !kubeNSNodes.isEmpty()) { if (kubeNSNodes.size() > 1) { context.log().warn("More than one KubeNamespace node have been found, juste taking the first one"); @@ -140,7 +173,7 @@ private void doProcess(KubernetesModifierContext context) { } // If a node of type KubeCluster is found in the topology, get the config and store it in the context for later usage - Set kubeClusterNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_KUBE_CLUSTER, false); + Set kubeClusterNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_KUBE_CLUSTER, false); if (kubeClusterNodes != null && !kubeClusterNodes.isEmpty()) { if (kubeClusterNodes.size() > 1) { context.log().warn("More than one KubeCluster node have been found, juste taking the first one"); @@ -151,7 +184,7 @@ private void doProcess(KubernetesModifierContext context) { String kubeConfig = ((ScalarPropertyValue)configPV).getValue(); if (StringUtils.isNotEmpty(kubeConfig)) { nsConfigPV = configPV; - if (StringUtils.isNotEmpty(namespace)) { + if (StringUtils.isNotEmpty(namespace)) { // update namespace in kube config if any Map kubeConf = (Map)YamlParserUtil.load(kubeConfig); List ct = (List)kubeConf.get("contexts"); @@ -171,7 +204,9 @@ private void doProcess(KubernetesModifierContext context) { if (StringUtils.isNotEmpty(namespace)) { /* add resource node to create namespace */ - kubeNSResourceNode = addNodeTemplate(null, topology, NAMESPACE_RESOURCE_NAME, K8S_TYPES_SIMPLE_RESOURCE, + kubeNSResourceNode = addNodeTemplate(context.getFlowExecutionContext(), null, + topology, NAMESPACE_RESOURCE_NAME, + K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); /* store node name in cache to be used for relations */ context.getFlowExecutionContext().getExecutionCache().put(NAMESPACE_RESOURCE_NAME, NAMESPACE_RESOURCE_NAME); @@ -187,40 +222,40 @@ private void doProcess(KubernetesModifierContext context) { /* properties map stored in cache will be used later to generate resource_def node property */ context.getYamlResources().put(NAMESPACE_RESOURCE_NAME, namespaceProperties); - setNodePropertyPathValue(null, topology, kubeNSResourceNode, "resource_id", kubeNSNode.getProperties().get("namespace")); + setNodePropertyPathValue(null, topology, kubeNSResourceNode, "resource_id", kubeNSNode.getProperties().get("namespace")); /* use original kube config for this node */ setNodePropertyPathValue(null, topology, kubeNSResourceNode, "kube_config", nsConfigPV); /* remove namespace node */ - removeNode (topology, kubeNSNode); + removeNode (context.getFlowExecutionContext(), topology, kubeNSNode); } // Endpoints - Set endpointNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_ENDPOINT_RESOURCE, false, true); + Set endpointNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_ENDPOINT_RESOURCE, false, true); endpointNodes.forEach(nodeTemplate -> manageEndpoints(context, nodeTemplate)); // Direct Connection - Set containerNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_KUBECONTAINER, true); + Set containerNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_KUBECONTAINER, true); containerNodes.forEach(nodeTemplate -> manageContainersDirectConnection(context, nodeTemplate)); // Create DeploymentResource for each Deployment - Set deploymentNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_KUBEDEPLOYMENT, false); + Set deploymentNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_KUBEDEPLOYMENT, false); deploymentNodes.forEach(nodeTemplate -> createDeploymentResource(context, nodeTemplate)); // Manage Services - Set services = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_KUBE_SERVICE, true, false); + Set services = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_KUBE_SERVICE, true, false); safe(services).forEach(nodeTemplate -> manageServiceRelationship(context, nodeTemplate)); services.forEach(nodeTemplate -> createServiceResource(context, nodeTemplate)); - Set ingress = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_KUBE_INGRESS, true, false); + Set ingress = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_KUBE_INGRESS, true, false); ingress.forEach(nodeTemplate -> createIngress(context,nodeTemplate)); // // for each Job create a node of type JobResource - // Set jobNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_JOB, false); + // Set jobNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_JOB, false); // jobNodes.forEach(nodeTemplate -> createJobResource(context, nodeTemplate)); // Replace all occurences of org.alien4cloud.nodes.DockerExtVolume by k8s abstract volumes - Set volumeNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_VOLUME_BASE, true); + Set volumeNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_VOLUME_BASE, true); volumeNodes.forEach(nodeTemplate -> manageVolumesAtachment(context, nodeTemplate)); // A function evaluator context will be useful @@ -253,17 +288,17 @@ private void doProcess(KubernetesModifierContext context) { // remove useless nodes // TODO bug on node matching view since these nodes are the real matched ones // TODO then find a way to delete servicesNodes and deloymentNodes as they are not used - services.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - ingress.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + services.forEach(nodeTemplate -> removeNode(context.getFlowExecutionContext(), topology, nodeTemplate)); + ingress.forEach(nodeTemplate -> removeNode(context.getFlowExecutionContext(), topology, nodeTemplate)); - deploymentNodes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + deploymentNodes.forEach(nodeTemplate -> removeNode(context.getFlowExecutionContext(), topology, nodeTemplate)); // jobNodes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - Set volumes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_VOLUME_BASE, true); - volumes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + Set volumes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_VOLUME_BASE, true); + volumes.forEach(nodeTemplate -> removeNode(context.getFlowExecutionContext(), topology, nodeTemplate)); - Set containers = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_APPLICATION_DOCKER_CONTAINER, true, false); - safe(containers).forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + Set containers = this.getNodesOfType(context.getFlowExecutionContext(), topology, A4C_TYPES_APPLICATION_DOCKER_CONTAINER, true, false); + safe(containers).forEach(nodeTemplate -> removeNode(context.getFlowExecutionContext(), topology, nodeTemplate)); String providedNamespace = getProvidedMetaproperty(context.getFlowExecutionContext(), K8S_NAMESPACE_METAPROP_NAME); if (providedNamespace != null) { @@ -271,9 +306,9 @@ private void doProcess(KubernetesModifierContext context) { } // finally set the 'resource_spec' property with the JSON content of the resource specification - Set resourceNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_BASE_RESOURCE, true); + Set resourceNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_BASE_RESOURCE, true); // also treat job resources - // Set jobResourceNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_BASE_JOB_RESOURCE, true); + // Set jobResourceNodes = this.getNodesOfType(context.getFlowExecutionContext(), topology, K8S_TYPES_BASE_JOB_RESOURCE, true); // for (NodeTemplate jobResourceNode : jobResourceNodes) { // resourceNodes.add(jobResourceNode); // } @@ -306,7 +341,7 @@ private void doProcess(KubernetesModifierContext context) { } } } - servicesToRemove.stream().forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + servicesToRemove.stream().forEach(nodeTemplate -> removeNode(context.getFlowExecutionContext(), topology, nodeTemplate)); } /** @@ -340,7 +375,7 @@ private void manageContainersDirectConnection(KubernetesModifierContext context, String targetCapabilityName = relationshipTemplate.getTargetedCapabilityName(); NodeTemplate targetNodeTemplate = context.getTopology().getNodeTemplates().get(relationshipTemplate.getTarget()); // add a service - NodeTemplate serviceNode = addNodeTemplate(context.getCsar(),context.getTopology(), nodeTemplate.getName() + "_" + relationshipTemplate.getRequirementName() + "_" + targetNodeTemplate.getName() + "_" + targetCapabilityName + "_Service", + NodeTemplate serviceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), nodeTemplate.getName() + "_" + relationshipTemplate.getRequirementName() + "_" + targetNodeTemplate.getName() + "_" + targetCapabilityName + "_Service", K8S_TYPES_KUBE_SERVICE, context.getKubeCsarVersion()); setNodePropertyPathValue(context.getCsar(), context.getTopology(), serviceNode, "spec.service_type", new ScalarPropertyValue("ClusterIP")); // add a relation between the service and the target container @@ -510,7 +545,7 @@ private Set demultiplexServices(Csar csar, Topology topology, Set< nodesToRemove.stream().forEach(s -> { serviceNodes.remove(s); // if the node to remove is the target of dependsOn relationship (a consumer), let's move it to the node we keep - removeNode(topology, s); + removeNode(context, topology, s); }); setNodeTagValue(nodeToKeep, A4C_KUBERNETES_MODIFIER_TAG_SERVICE_ENDPOINTS, nodeToKeepServiceEndpointTag.toString()); @@ -625,7 +660,7 @@ private void manageVolume(KubernetesModifierContext context, NodeTemplate volume NodeType volumeNodeType = ToscaContext.get(NodeType.class, volumeNode.getType()); if (ToscaTypeUtils.isOfType(volumeNodeType, KubeTopologyUtils.K8S_TYPES_SECRET_VOLUME)) { // we must create a secret, the deployment should depend on it - NodeTemplate secretFactory = addNodeTemplate(context.getCsar(),context.getTopology(), volumeNode.getName() + "_Secret", KubeTopologyUtils.K8S_TYPES_SECRET_FACTORY, + NodeTemplate secretFactory = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), volumeNode.getName() + "_Secret", KubeTopologyUtils.K8S_TYPES_SECRET_FACTORY, context.getKubeCsarVersion()); setKubeConfig(context, secretFactory); String secretName = generateUniqueKubeName(context.getFlowExecutionContext(), volumeNode.getName()); @@ -649,7 +684,7 @@ private void managePersistentVolumeClaim(KubernetesModifierContext context, Node if (ToscaTypeUtils.isOfType(volumeNodeType, KubeTopologyUtils.K8S_TYPES_VOLUMES_CLAIM)) { AbstractPropertyValue claimNamePV = PropertyUtil.getPropertyValueFromPath(volumeNode.getProperties(), "spec.claimName"); if (claimNamePV == null) { - NodeTemplate volumeClaimResource = addNodeTemplate(context.getCsar(),context.getTopology(), volumeNode.getName() + "_PVC", KubeTopologyUtils.K8S_TYPES_SIMPLE_RESOURCE, + NodeTemplate volumeClaimResource = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), volumeNode.getName() + "_PVC", KubeTopologyUtils.K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, volumeClaimResource); @@ -716,7 +751,7 @@ private void manageAutoScaling(KubernetesModifierContext context, PolicyTemplate private void addHorizontalPodAutoScalingResource(KubernetesModifierContext context, PolicyTemplate policyTemplate, NodeTemplate target) { String resourceBaseName = target.getName() + "_" + policyTemplate.getName(); - NodeTemplate podAutoScalerResourceNode = addNodeTemplate(context.getCsar(),context.getTopology(), resourceBaseName + "_Resource", K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); + NodeTemplate podAutoScalerResourceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), resourceBaseName + "_Resource", K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, podAutoScalerResourceNode); Map podAutoScalerResourceNodeProperties = Maps.newHashMap(); @@ -1055,7 +1090,7 @@ private void manageContainer(KubernetesModifierContext context, NodeTemplate con String input_prefix = config_setting_map.get("input_prefix"); String config_path = config_setting_map.get("config_path"); - NodeTemplate configMapFactoryNode = addNodeTemplate(context.getCsar(),context.getTopology(), containerNode.getName() + "_ConfigMap_" + input_prefix, KubeTopologyUtils.K8S_TYPES_CONFIG_MAP_FACTORY, + NodeTemplate configMapFactoryNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), containerNode.getName() + "_ConfigMap_" + input_prefix, KubeTopologyUtils.K8S_TYPES_CONFIG_MAP_FACTORY, context.getKubeCsarVersion()); setKubeConfig(context, configMapFactoryNode); @@ -1239,7 +1274,7 @@ private void manageContainerEndpoint(Csar csar, Topology topology, NodeTemplate } private void createJobResource(KubernetesModifierContext context, NodeTemplate jobNode) { - NodeTemplate jobResourceNode = addNodeTemplate(context.getCsar(),context.getTopology(), jobNode.getName() + "_Resource", K8S_TYPES_JOB_RESOURCE, + NodeTemplate jobResourceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), jobNode.getName() + "_Resource", K8S_TYPES_JOB_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, jobResourceNode); context.getReplacements().put(jobNode.getName(), jobResourceNode); @@ -1268,7 +1303,7 @@ private void createDeploymentResource(KubernetesModifierContext context,NodeTemp setNodePropertyPathValue(context.getCsar(), context.getTopology(), deploymentNode, "spec.template.metadata.labels.app", deploymentName); setNodePropertyPathValue(context.getCsar(), context.getTopology(), deploymentNode, "spec.selector.matchLabels.app", deploymentName); - NodeTemplate deploymentResourceNode = addNodeTemplate(context.getCsar(),context.getTopology(), deploymentNode.getName() + "_Resource", K8S_TYPES_DEPLOYMENT_RESOURCE, + NodeTemplate deploymentResourceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), deploymentNode.getName() + "_Resource", K8S_TYPES_DEPLOYMENT_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, deploymentResourceNode); context.getReplacements().put(deploymentNode.getName(), deploymentResourceNode); @@ -1338,7 +1373,7 @@ private void createServiceResource(KubernetesModifierContext context, NodeTempla } } - NodeTemplate serviceResourceNode = addNodeTemplate(context.getCsar(),context.getTopology(), serviceNode.getName() + "_Resource", K8S_TYPES_SERVICE_RESOURCE, context.getKubeCsarVersion()); + NodeTemplate serviceResourceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), serviceNode.getName() + "_Resource", K8S_TYPES_SERVICE_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, serviceResourceNode); setNodeTagValue(serviceResourceNode, A4C_KUBERNETES_ADAPTER_MODIFIER_TAG_REPLACEMENT_NODE_FOR, serviceNode.getName()); @@ -1435,7 +1470,7 @@ private void createServiceResource(KubernetesModifierContext context, NodeTempla private void createIngress(KubernetesModifierContext context, NodeTemplate ingressNode) { Set relationshipTemplates = TopologyNavigationUtil.getTargetRelationships(ingressNode,"expose"); - NodeTemplate ingressResourceNode = addNodeTemplate(context.getCsar(),context.getTopology(), ingressNode.getName() + "_Resource", K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); + NodeTemplate ingressResourceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), ingressNode.getName() + "_Resource", K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, ingressResourceNode); setNodeTagValue(ingressResourceNode, A4C_KUBERNETES_ADAPTER_MODIFIER_TAG_REPLACEMENT_NODE_FOR, ingressNode.getName()); @@ -1516,7 +1551,7 @@ private void createIngress(KubernetesModifierContext context, NodeTemplate ingre if (StringUtils.isNoneEmpty(ingressCrt) && StringUtils.isNoneEmpty(ingressKey)) { // create the secret - NodeTemplate secretResourceNode = addNodeTemplate(context.getCsar(),context.getTopology(), ingressNode.getName() + "_Secret", K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); + NodeTemplate secretResourceNode = addNodeTemplate(context.getFlowExecutionContext(), context.getCsar(),context.getTopology(), ingressNode.getName() + "_Secret", K8S_TYPES_SIMPLE_RESOURCE, context.getKubeCsarVersion()); setKubeConfig(context, secretResourceNode); Map ingressSecretResourceNodeProperties = Maps.newHashMap(); diff --git a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java index dbc8c37..862a094 100644 --- a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java +++ b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java @@ -138,7 +138,7 @@ public T findElement(Class clazz, String elemen private void doProcess(Topology topology, FlowExecutionContext context) { Csar csar = new Csar(topology.getArchiveName(), topology.getArchiveVersion()); - Set endpointNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_ENDPOINT_RESOURCE, false, true); + Set endpointNodes = this.getNodesOfType(context, topology, K8S_TYPES_ENDPOINT_RESOURCE, false, true); endpointNodes.forEach(nodeTemplate -> manageEndpoints(context, csar, topology, nodeTemplate)); // just a map that store the node name as key and the replacement node as value @@ -150,21 +150,21 @@ private void doProcess(Topology topology, FlowExecutionContext context) { Map> resourceNodeYamlStructures = Maps.newHashMap(); // for each Service create a node of type ServiceResource - Set serviceNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_SERVICE, true); + Set serviceNodes = this.getNodesOfType(context, topology, K8S_TYPES_SERVICE, true); serviceNodes = demultiplexServices(csar, topology, serviceNodes, context); serviceNodes.forEach(nodeTemplate -> createServiceResource(csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures, context)); // for each Deployment create a node of type DeploymentResource - Set deploymentNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_DEPLOYMENT, false); - deploymentNodes.forEach(nodeTemplate -> createDeploymentResource(csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures)); + Set deploymentNodes = this.getNodesOfType(context, topology, K8S_TYPES_DEPLOYMENT, false); + deploymentNodes.forEach(nodeTemplate -> createDeploymentResource(context, csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures)); // for each StatefulSet create a node of type StatefulSetResource - Set statefulSetNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_STATEFULSET, false); + Set statefulSetNodes = this.getNodesOfType(context, topology, K8S_TYPES_STATEFULSET, false); statefulSetNodes.forEach(nodeTemplate -> createStatefulSetResource(csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures, context)); // for each Job create a node of type JobResource - Set jobNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_JOB, false); - jobNodes.forEach(nodeTemplate -> createJobResource(csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures)); + Set jobNodes = this.getNodesOfType(context, topology, K8S_TYPES_JOB, false); + jobNodes.forEach(nodeTemplate -> createJobResource(context, csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures)); // A function evaluator context will be usefull // FIXME: use topology inputs ? @@ -174,13 +174,13 @@ private void doProcess(Topology topology, FlowExecutionContext context) { Map> serviceIpAddressesPerDeploymentResource = Maps.newHashMap(); // for each container, - Set containerNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_CONTAINER, false); + Set containerNodes = this.getNodesOfType(context, topology, K8S_TYPES_CONTAINER, false); containerNodes.forEach( nodeTemplate -> manageContainer(csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures, functionEvaluatorContext, serviceIpAddressesPerDeploymentResource, context)); // for each volume node, populate the 'volumes' property of the corresponding deployment resource - Set volumeNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_VOLUME_BASE, true); + Set volumeNodes = this.getNodesOfType(context, topology, K8S_TYPES_VOLUME_BASE, true); volumeNodes.forEach(nodeTemplate -> manageVolume(context, csar, topology, nodeTemplate, nodeReplacementMap, resourceNodeYamlStructures)); // check auto-scaling policies and build the equiv node @@ -190,23 +190,23 @@ private void doProcess(Topology topology, FlowExecutionContext context) { // remove useless nodes // TODO bug on node matching view since these nodes are the real matched ones // TODO then find a way to delete servicesNodes and deloymentNodes as they are not used - serviceNodes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - deploymentNodes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - jobNodes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - statefulSetNodes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - Set volumes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_VOLUME_BASE, true); - volumes.forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); - Set containers = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_APPLICATION_DOCKER_CONTAINER, true, false); - safe(containers).forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + serviceNodes.forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); + deploymentNodes.forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); + jobNodes.forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); + statefulSetNodes.forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); + Set volumes = this.getNodesOfType(context, topology, K8S_TYPES_VOLUME_BASE, true); + volumes.forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); + Set containers = this.getNodesOfType(context, topology, A4C_TYPES_APPLICATION_DOCKER_CONTAINER, true, false); + safe(containers).forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); String providedNamespace = getProvidedMetaproperty(context, K8S_NAMESPACE_METAPROP_NAME); if (providedNamespace != null) { context.getLog().info("All resources will be created into the namespace <" + providedNamespace + ">"); } // finally set the 'resource_spec' property with the JSON content of the resource specification - Set resourceNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_BASE_RESOURCE, true); + Set resourceNodes = this.getNodesOfType(context, topology, K8S_TYPES_BASE_RESOURCE, true); // also treat job resources - Set jobResourceNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_BASE_JOB_RESOURCE, true); + Set jobResourceNodes = this.getNodesOfType(context, topology, K8S_TYPES_BASE_JOB_RESOURCE, true); for (NodeTemplate jobResourceNode : jobResourceNodes) { resourceNodes.add(jobResourceNode); } @@ -238,7 +238,7 @@ private void doProcess(Topology topology, FlowExecutionContext context) { } } } - servicesToRemove.stream().forEach(nodeTemplate -> removeNode(topology, nodeTemplate)); + servicesToRemove.stream().forEach(nodeTemplate -> removeNode(context, topology, nodeTemplate)); } @@ -331,7 +331,7 @@ private Set demultiplexServices(Csar csar, Topology topology, Set< nodesToRemove.stream().forEach(s -> { serviceNodes.remove(s); // if the node to remove is the target of dependsOn relationship (a consumer), let's move it to the node we keep - removeNode(topology, s); + removeNode(context, topology, s); }); setNodeTagValue(nodeToKeep, A4C_KUBERNETES_MODIFIER_TAG_SERVICE_ENDPOINTS, nodeToKeepServiceEndpointTag.toString()); @@ -410,7 +410,7 @@ private void manageEndpoints(FlowExecutionContext context, Csar csar, Topology t setNodePropertyPathValue(csar, topology, endpointNode, "subsets", subsets); } - private void manageVolume(FlowExecutionContext ctx, Csar csar, Topology topology, NodeTemplate volumeNode, Map nodeReplacementMap, + private void manageVolume(FlowExecutionContext context, Csar csar, Topology topology, NodeTemplate volumeNode, Map nodeReplacementMap, Map> resourceNodeYamlStructures) { // FIXME : doesn't support many attachement (1 volume -> many containers) ?) @@ -429,7 +429,7 @@ private void manageVolume(FlowExecutionContext ctx, Csar csar, Topology topology hostOfContainer = TopologyNavigationUtil.getHostOfTypeInHostingHierarchy(topology, targetContainer, K8S_TYPES_STATEFULSET); } if (hostOfContainer == null) { - ctx.getLog().error("failed to get controller hosting volume <"+ volumeNode.getName() + ">"); + context.getLog().error("failed to get controller hosting volume <"+ volumeNode.getName() + ">"); return; } // get the deployment resource corresponding to this deployment @@ -440,12 +440,12 @@ private void manageVolume(FlowExecutionContext ctx, Csar csar, Topology topology if(ToscaTypeUtils.isOfType(hostNodeType, K8S_TYPES_STATEFULSET)){ // If statefulSet does not match a PVC, raise error if(!ToscaTypeUtils.isOfType(volumeNodeType, KubeTopologyUtils.K8S_TYPES_VOLUMES_CLAIM)){ - ctx.log().error("StatefulSet "+hostOfContainer.getName()+" should match a PersistentVolumeClaim resource !"); + context.log().error("StatefulSet "+hostOfContainer.getName()+" should match a PersistentVolumeClaim resource !"); return; } - manageVolumeClaimTemplates(ctx, csar, topology, volumeNode, resourceNodeYamlStructures, controllerResourceNode); + manageVolumeClaimTemplates(context, csar, topology, volumeNode, resourceNodeYamlStructures, controllerResourceNode); }else{ - managePersistentVolumeClaim(ctx, csar, topology, volumeNode, resourceNodeYamlStructures, controllerResourceNode); + managePersistentVolumeClaim(context, csar, topology, volumeNode, resourceNodeYamlStructures, controllerResourceNode); } Map deploymentResourceNodeProperties = resourceNodeYamlStructures.get(controllerResourceNode.getName()); @@ -465,9 +465,9 @@ private void manageVolume(FlowExecutionContext ctx, Csar csar, Topology topology if (ToscaTypeUtils.isOfType(volumeNodeType, KubeTopologyUtils.K8S_TYPES_SECRET_VOLUME)) { // we must create a secret, the deployment should depend on it - NodeTemplate secretFactory = addNodeTemplate(csar, topology, volumeNode.getName() + "_Secret", KubeTopologyUtils.K8S_TYPES_SECRET_FACTORY, + NodeTemplate secretFactory = addNodeTemplate(context, csar, topology, volumeNode.getName() + "_Secret", KubeTopologyUtils.K8S_TYPES_SECRET_FACTORY, K8S_CSAR_VERSION); - String secretName = generateUniqueKubeName(ctx, volumeNode.getName()); + String secretName = generateUniqueKubeName(context, volumeNode.getName()); setNodePropertyPathValue(csar, topology, secretFactory, "name", new ScalarPropertyValue(secretName)); // we must also define the secretName of the secret TopologyModifierSupport.feedMapOrComplexPropertyEntry(volumeSpecObject, "secretName", secretName); @@ -484,11 +484,11 @@ private void manageVolume(FlowExecutionContext ctx, Csar csar, Topology topology } - private void manageVolumeClaimTemplates(FlowExecutionContext ctx, Csar csar, Topology topology, NodeTemplate volumeNode, + private void manageVolumeClaimTemplates(FlowExecutionContext context, Csar csar, Topology topology, NodeTemplate volumeNode, Map> resourceNodeYamlStructures, NodeTemplate statefulsetResourceNode) { AbstractPropertyValue size = PropertyUtil.getPropertyValueFromPath(volumeNode.getProperties(), "size"); if(size ==null){ - ctx.log().error("Volume node "+volumeNode.getName()+" should have a size !"); + context.log().error("Volume node "+volumeNode.getName()+" should have a size !"); } NodeType nodeType = ToscaContext.get(NodeType.class, volumeNode.getType()); @@ -523,20 +523,20 @@ private void manageVolumeClaimTemplates(FlowExecutionContext ctx, Csar csar, Top } - private void managePersistentVolumeClaim(FlowExecutionContext ctx, Csar csar, Topology topology, NodeTemplate volumeNode, + private void managePersistentVolumeClaim(FlowExecutionContext context, Csar csar, Topology topology, NodeTemplate volumeNode, Map> resourceNodeYamlStructures, NodeTemplate deploymentResourceNode) { // in case of empty claimName for a PersistentVolumeClaimSource then create a node of type PersistentVolumeClaim NodeType volumeNodeType = ToscaContext.get(NodeType.class, volumeNode.getType()); if (ToscaTypeUtils.isOfType(volumeNodeType, KubeTopologyUtils.K8S_TYPES_VOLUMES_CLAIM)) { AbstractPropertyValue claimNamePV = PropertyUtil.getPropertyValueFromPath(volumeNode.getProperties(), "spec.claimName"); if (claimNamePV == null) { - NodeTemplate volumeClaimResource = addNodeTemplate(csar, topology, volumeNode.getName() + "_PVC", KubeTopologyUtils.K8S_TYPES_SIMPLE_RESOURCE, + NodeTemplate volumeClaimResource = addNodeTemplate(context, csar, topology, volumeNode.getName() + "_PVC", KubeTopologyUtils.K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); Map volumeClaimResourceNodeProperties = Maps.newHashMap(); resourceNodeYamlStructures.put(volumeClaimResource.getName(), volumeClaimResourceNodeProperties); - String claimName = generateUniqueKubeName(ctx, volumeNode.getName()); + String claimName = generateUniqueKubeName(context, volumeNode.getName()); // fill the node properties feedPropertyValue(volumeClaimResource.getProperties(), "resource_type", new ScalarPropertyValue("pvc"), false); feedPropertyValue(volumeClaimResource.getProperties(), "resource_id", new ScalarPropertyValue(claimName), false); @@ -553,7 +553,7 @@ private void managePersistentVolumeClaim(FlowExecutionContext ctx, Csar csar, To NodeType nodeType = ToscaContext.get(NodeType.class, volumeNode.getType()); AbstractPropertyValue size = PropertyUtil.getPropertyValueFromPath(volumeNode.getProperties(), "size"); if(size ==null){ - ctx.log().error("Volume node "+volumeNode.getName()+" should have a size !"); + context.log().error("Volume node "+volumeNode.getName()+" should have a size !"); } PropertyDefinition propertyDefinition = nodeType.getProperties().get("size"); Object transformedSize = getTransformedValue(size, propertyDefinition, ""); @@ -598,17 +598,17 @@ private void manageAutoScaling(Csar csar, Topology topology, PolicyTemplate poli } - private void addHorizontalPodAutoScalingResource(FlowExecutionContext ctx, Csar csar, Topology topology, PolicyTemplate policyTemplate, NodeTemplate target, + private void addHorizontalPodAutoScalingResource(FlowExecutionContext context, Csar csar, Topology topology, PolicyTemplate policyTemplate, NodeTemplate target, Map nodeReplacementMap, Map> resourceNodeYamlStructures) { String resourceBaseName = target.getName() + "_" + policyTemplate.getName(); - NodeTemplate podAutoScalerResourceNode = addNodeTemplate(csar, topology, resourceBaseName + "_Resource", K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); + NodeTemplate podAutoScalerResourceNode = addNodeTemplate(context, csar, topology, resourceBaseName + "_Resource", K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); Map podAutoScalerResourceNodeProperties = Maps.newHashMap(); resourceNodeYamlStructures.put(podAutoScalerResourceNode.getName(), podAutoScalerResourceNodeProperties); NodeTemplate targetDeploymentResourceNode = nodeReplacementMap.get(target.getName()); Map targetDeploymentResourceNodeProps = resourceNodeYamlStructures.get(targetDeploymentResourceNode.getName()); - String podAutoScalerName = generateUniqueKubeName(ctx, resourceBaseName); + String podAutoScalerName = generateUniqueKubeName(context, resourceBaseName); feedPropertyValue(podAutoScalerResourceNode.getProperties(), "resource_type", new ScalarPropertyValue("hpa"), false); feedPropertyValue(podAutoScalerResourceNode.getProperties(), "resource_id", new ScalarPropertyValue(podAutoScalerName), false); @@ -775,7 +775,7 @@ private void manageContainer(Csar csar, Topology topology, NodeTemplate containe String input_prefix = config_setting_map.get("input_prefix"); String config_path = config_setting_map.get("config_path"); - NodeTemplate configMapFactoryNode = addNodeTemplate(csar, topology, nodeTemplate.getName() + "_ConfigMap_" + input_prefix, KubeTopologyUtils.K8S_TYPES_CONFIG_MAP_FACTORY, + NodeTemplate configMapFactoryNode = addNodeTemplate(context, csar, topology, nodeTemplate.getName() + "_ConfigMap_" + input_prefix, KubeTopologyUtils.K8S_TYPES_CONFIG_MAP_FACTORY, K8S_CSAR_VERSION); AbstractPropertyValue containerNameAPV = PropertyUtil.getPropertyValueFromPath(safe(containerNode.getProperties()), "container.name"); String containerName = ((ScalarPropertyValue)containerNameAPV).getValue(); @@ -926,7 +926,7 @@ private void manageContainer(Csar csar, Topology topology, NodeTemplate containe private void createStatefulSetResource(Csar csar, Topology topology, NodeTemplate statefulsetNode, Map nodeReplacementMap, Map> resourceNodeYamlStructures , FlowExecutionContext context){ - NodeTemplate statefulsetResourceNode = addNodeTemplate(csar, topology, statefulsetNode.getName() + "_Resource", K8S_TYPES_STATEFULSET_RESOURCE, + NodeTemplate statefulsetResourceNode = addNodeTemplate(context, csar, topology, statefulsetNode.getName() + "_Resource", K8S_TYPES_STATEFULSET_RESOURCE, K8S_CSAR_VERSION); nodeReplacementMap.put(statefulsetNode.getName(), statefulsetResourceNode); setNodeTagValue(statefulsetResourceNode, A4C_KUBERNETES_MODIFIER_TAG + "_created_from", statefulsetNode.getName()); @@ -1013,9 +1013,9 @@ private void createStatefulSetResource(Csar csar, Topology topology, NodeTemplat } - private void createJobResource(Csar csar, Topology topology, NodeTemplate jobNode, Map nodeReplacementMap, + private void createJobResource(FlowExecutionContext context, Csar csar, Topology topology, NodeTemplate jobNode, Map nodeReplacementMap, Map> resourceNodeYamlStructures) { - NodeTemplate jobResourceNode = addNodeTemplate(csar, topology, jobNode.getName() + "_Resource", K8S_TYPES_JOB_RESOURCE, + NodeTemplate jobResourceNode = addNodeTemplate(context, csar, topology, jobNode.getName() + "_Resource", K8S_TYPES_JOB_RESOURCE, K8S_CSAR_VERSION); nodeReplacementMap.put(jobNode.getName(), jobResourceNode); setNodeTagValue(jobResourceNode, A4C_KUBERNETES_MODIFIER_TAG + "_created_from", jobNode.getName()); @@ -1035,9 +1035,9 @@ private void createJobResource(Csar csar, Topology topology, NodeTemplate jobNod } - private void createDeploymentResource(Csar csar, Topology topology, NodeTemplate deploymentNode, Map nodeReplacementMap, + private void createDeploymentResource(FlowExecutionContext context, Csar csar, Topology topology, NodeTemplate deploymentNode, Map nodeReplacementMap, Map> resourceNodeYamlStructures) { - NodeTemplate deploymentResourceNode = addNodeTemplate(csar, topology, deploymentNode.getName() + "_Resource", K8S_TYPES_DEPLOYMENT_RESOURCE, + NodeTemplate deploymentResourceNode = addNodeTemplate(context, csar, topology, deploymentNode.getName() + "_Resource", K8S_TYPES_DEPLOYMENT_RESOURCE, K8S_CSAR_VERSION); nodeReplacementMap.put(deploymentNode.getName(), deploymentResourceNode); setNodeTagValue(deploymentResourceNode, A4C_KUBERNETES_MODIFIER_TAG + "_created_from", deploymentNode.getName()); @@ -1114,7 +1114,7 @@ private void createServiceResource(Csar csar, Topology topology, NodeTemplate se } } - NodeTemplate serviceResourceNode = addNodeTemplate(csar, topology, serviceNode.getName() + "_Resource", K8S_TYPES_SERVICE_RESOURCE, K8S_CSAR_VERSION); + NodeTemplate serviceResourceNode = addNodeTemplate(context, csar, topology, serviceNode.getName() + "_Resource", K8S_TYPES_SERVICE_RESOURCE, K8S_CSAR_VERSION); // prepare attributes Map> topologyAttributes = topology.getOutputAttributes(); @@ -1182,19 +1182,19 @@ private void createServiceResource(Csar csar, Topology topology, NodeTemplate se } if (serviceNode.getType().equals(K8S_TYPES_SERVICE_INGRESS)) { - createIngress(context, csar, topology, serviceNode, serviceResourceNode, portName, namePropertyValue, resourceNodeYamlStructures, context); + createIngress(context, csar, topology, serviceNode, serviceResourceNode, portName, namePropertyValue, resourceNodeYamlStructures); } } - private void createIngress(FlowExecutionContext ctx, Csar csar, Topology topology, NodeTemplate serviceNode, NodeTemplate serviceResourcesNode, String portName, AbstractPropertyValue serviceName, Map> resourceNodeYamlStructures, FlowExecutionContext context) { + private void createIngress(FlowExecutionContext context, Csar csar, Topology topology, NodeTemplate serviceNode, NodeTemplate serviceResourcesNode, String portName, AbstractPropertyValue serviceName, Map> resourceNodeYamlStructures) { AbstractPropertyValue ingressHost = PropertyUtil.getPropertyValueFromPath(safe(serviceNode.getProperties()), "host"); - NodeTemplate ingressResourceNode = addNodeTemplate(csar, topology, serviceNode.getName() + "_Ingress", K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); + NodeTemplate ingressResourceNode = addNodeTemplate(context, csar, topology, serviceNode.getName() + "_Ingress", K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); Map ingressResourceNodeProperties = Maps.newHashMap(); resourceNodeYamlStructures.put(ingressResourceNode.getName(), ingressResourceNodeProperties); - String ingressName = generateUniqueKubeName(ctx, ingressResourceNode.getName()); + String ingressName = generateUniqueKubeName(context, ingressResourceNode.getName()); feedPropertyValue(ingressResourceNode.getProperties(), "resource_type", new ScalarPropertyValue("ing"), false); feedPropertyValue(ingressResourceNode.getProperties(), "resource_id", new ScalarPropertyValue(ingressName), false); @@ -1253,12 +1253,12 @@ private void createIngress(FlowExecutionContext ctx, Csar csar, Topology topolog } if (StringUtils.isNoneEmpty(ingressCrt) && StringUtils.isNoneEmpty(ingressKey)) { // create the secret - NodeTemplate secretResourceNode = addNodeTemplate(csar, topology, serviceNode.getName() + "_IngressSecret", K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); + NodeTemplate secretResourceNode = addNodeTemplate(context, csar, topology, serviceNode.getName() + "_IngressSecret", K8S_TYPES_SIMPLE_RESOURCE, K8S_CSAR_VERSION); Map ingressSecretResourceNodeProperties = Maps.newHashMap(); resourceNodeYamlStructures.put(secretResourceNode.getName(), ingressSecretResourceNodeProperties); - String ingressSecretName = generateUniqueKubeName(ctx, secretResourceNode.getName()); + String ingressSecretName = generateUniqueKubeName(context, secretResourceNode.getName()); feedPropertyValue(secretResourceNode.getProperties(), "resource_type", new ScalarPropertyValue("secrets"), false); feedPropertyValue(secretResourceNode.getProperties(), "resource_id", new ScalarPropertyValue(ingressSecretName), false); diff --git a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesLocationTopologyModifier.java b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesLocationTopologyModifier.java index df4d3a0..5c39542 100644 --- a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesLocationTopologyModifier.java +++ b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesLocationTopologyModifier.java @@ -107,26 +107,26 @@ private void doProcess(Topology topology, FlowExecutionContext context) { Csar csar = new Csar(topology.getArchiveName(), topology.getArchiveVersion()); // replace all ContainerRuntime by org.alien4cloud.kubernetes.api.types.AbstractContainer - Set containerRuntimeNodes = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_CONTAINER_RUNTIME, false); + Set containerRuntimeNodes = this.getNodesOfType(context, topology, A4C_TYPES_CONTAINER_RUNTIME, false); containerRuntimeNodes.forEach(nodeTemplate -> transformContainerRuntime(csar, topology, context, nodeTemplate)); // replace all ContainerDeploymentUnit by org.alien4cloud.kubernetes.api.types.AbstractController - Set containerDeploymentUnitNodes = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_CONTAINER_DEPLOYMENT_UNIT, false); + Set containerDeploymentUnitNodes = this.getNodesOfType(context, topology, A4C_TYPES_CONTAINER_DEPLOYMENT_UNIT, false); containerDeploymentUnitNodes.forEach(nodeTemplate -> transformContainerDeploymentUnit(csar, topology, context, nodeTemplate)); // replace all ContainerJobUnit by org.alien4cloud.kubernetes.api.types.AbstractJob - Set containerJobUnitNodes = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_CONTAINER_JOB_UNIT, false); + Set containerJobUnitNodes = this.getNodesOfType(context, topology, A4C_TYPES_CONTAINER_JOB_UNIT, false); containerJobUnitNodes.forEach(nodeTemplate -> transformContainerJobUnit(csar, topology, context, nodeTemplate)); // for each container capability of type endpoint // - add a org.alien4cloud.kubernetes.api.types.ServiceResource and weave depends_on relationships // - populate properties on the K8S AbstractContainer that host the container image - Set containerNodes = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_APPLICATION_DOCKER_CONTAINER, true, false); + Set containerNodes = this.getNodesOfType(context, topology, A4C_TYPES_APPLICATION_DOCKER_CONTAINER, true, false); containerNodes.forEach(nodeTemplate -> manageContainer(csar, topology, nodeTemplate, containerNodes, context)); manageContainerHybridConnections(context, csar, topology, containerNodes); // replace all occurences of org.alien4cloud.nodes.DockerExtVolume by k8s abstract volumes - Set volumeNodes = TopologyNavigationUtil.getNodesOfType(topology, A4C_TYPES_DOCKER_VOLUME, true); + Set volumeNodes = this.getNodesOfType(context, topology, A4C_TYPES_DOCKER_VOLUME, true); volumeNodes.forEach(nodeTemplate -> manageVolumes(csar, topology, nodeTemplate)); } @@ -174,7 +174,7 @@ private void manageContainerHybridConnection(FlowExecutionContext context, Csar NodeTemplate targetNodeTemplate, String endpointName) { // add an abstract service node - NodeTemplate serviceNode = addNodeTemplate(csar, topology, targetNodeTemplate.getName() + "_" + endpointName + "_Service", K8S_TYPES_ABSTRACT_SERVICE, + NodeTemplate serviceNode = addNodeTemplate(context, csar, topology, targetNodeTemplate.getName() + "_" + endpointName + "_Service", K8S_TYPES_ABSTRACT_SERVICE, K8S_CSAR_VERSION); setNodeTagValue(serviceNode, A4C_KUBERNETES_MODIFIER_TAG, "Proxy of node <" + targetNodeTemplate.getName() + "> capability <" + endpointName + ">"); setNodeTagValue(serviceNode, A4C_KUBERNETES_MODIFIER_TAG_SERVICE_ENDPOINT, endpointName); @@ -193,7 +193,7 @@ private void manageContainerHybridConnection(FlowExecutionContext context, Csar } // create the resource endpoint - NodeTemplate endpointNode = addNodeTemplate(csar, topology, targetNodeTemplate.getName() + "_" + endpointName + "_ServiceEndpoint", + NodeTemplate endpointNode = addNodeTemplate(context, csar, topology, targetNodeTemplate.getName() + "_" + endpointName + "_ServiceEndpoint", K8S_TYPES_ENDPOINT_RESOURCE, K8S_CSAR_VERSION); setNodePropertyPathValue(csar, topology, endpointNode, "resource_id", new ScalarPropertyValue(serviceName)); @@ -320,7 +320,7 @@ private void transformContainerJobUnit(Csar csar, Topology topology, FlowExecuti * Wrap this node of type AbstractContainer into a node of type AbstractDeployment. */ private void wrapInAbstractDeployment(Csar csar, Topology topology, FlowExecutionContext context, NodeTemplate nodeTemplate) { - NodeTemplate hostNode = addNodeTemplate(csar, topology, nodeTemplate.getName() + "Deployment", K8S_TYPES_ABSTRACT_DEPLOYMENT, K8S_CSAR_VERSION); + NodeTemplate hostNode = addNodeTemplate(context, csar, topology, nodeTemplate.getName() + "Deployment", K8S_TYPES_ABSTRACT_DEPLOYMENT, K8S_CSAR_VERSION); setNodeTagValue(hostNode, A4C_KUBERNETES_MODIFIER_TAG, "Created to host " + nodeTemplate.getName()); // set a generated name to the K8S object @@ -469,7 +469,7 @@ private void manageContainerEndpoints(Csar csar, Topology topology, NodeTemplate */ if (endpointNames.size() > 0) { // Create the service - NodeTemplate serviceNode = addNodeTemplate(csar, topology, containerNodeTemplate.getName() + "_" + controllerNodeTemplate.getName() + "_Service", + NodeTemplate serviceNode = addNodeTemplate(context, csar, topology, containerNodeTemplate.getName() + "_" + controllerNodeTemplate.getName() + "_Service", K8S_TYPES_ABSTRACT_SERVICE, K8S_CSAR_VERSION); setNodePropertyPathValue(csar, topology, serviceNode, "metadata.name", new ScalarPropertyValue(generateUniqueKubeName(context, serviceNode.getName()))); setNodePropertyPathValue(csar, topology, serviceNode, "spec.service_type", new ScalarPropertyValue("NodePort")); diff --git a/src/test/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAutomatchingTopologyModifier.java b/src/test/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAutomatchingTopologyModifier.java index 93a6b7e..b9692d8 100644 --- a/src/test/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAutomatchingTopologyModifier.java +++ b/src/test/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesAutomatchingTopologyModifier.java @@ -1,19 +1,24 @@ package org.alien4cloud.plugin.kubernetes.modifier; -import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.*; import static org.alien4cloud.plugin.kubernetes.csar.Version.K8S_CSAR_VERSION; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_ABSTRACT_CONTAINER; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_ABSTRACT_DEPLOYMENT; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_ABSTRACT_SERVICE; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_CONTAINER; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_DEPLOYMENT; +import static org.alien4cloud.plugin.kubernetes.modifier.KubeTopologyUtils.K8S_TYPES_SERVICE; + +import java.util.Set; -import alien4cloud.tosca.context.ToscaContextual; -import lombok.extern.java.Log; import org.alien4cloud.alm.deployment.configuration.flow.FlowExecutionContext; import org.alien4cloud.alm.deployment.configuration.flow.TopologyModifierSupport; import org.alien4cloud.tosca.model.Csar; import org.alien4cloud.tosca.model.templates.NodeTemplate; import org.alien4cloud.tosca.model.templates.Topology; -import org.alien4cloud.tosca.utils.TopologyNavigationUtil; import org.springframework.stereotype.Component; -import java.util.Set; +import alien4cloud.tosca.context.ToscaContextual; +import lombok.extern.java.Log; /** * Just for tests : simulate matching by replacing all K8S abstract nodes by it's Concrete implem. @@ -30,17 +35,17 @@ public void process(Topology topology, FlowExecutionContext context) { Csar csar = new Csar(topology.getArchiveName(), topology.getArchiveVersion()); // replace each AbstractContainer by Container - Set containerNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_ABSTRACT_CONTAINER, false); + Set containerNodes = this.getNodesOfType(context, topology, K8S_TYPES_ABSTRACT_CONTAINER, false); containerNodes.forEach(nodeTemplate -> { replaceNode(csar, topology, nodeTemplate, K8S_TYPES_CONTAINER, K8S_CSAR_VERSION); }); // replace each AbstractService by Service - Set serviceNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_ABSTRACT_SERVICE, false); + Set serviceNodes = this.getNodesOfType(context, topology, K8S_TYPES_ABSTRACT_SERVICE, false); serviceNodes.forEach(nodeTemplate -> { replaceNode(csar, topology, nodeTemplate, K8S_TYPES_SERVICE, K8S_CSAR_VERSION); }); // replace each AbstractDeployment by Deployment - Set deploymentNodes = TopologyNavigationUtil.getNodesOfType(topology, K8S_TYPES_ABSTRACT_DEPLOYMENT, false); + Set deploymentNodes = this.getNodesOfType(context, topology, K8S_TYPES_ABSTRACT_DEPLOYMENT, false); deploymentNodes.forEach(nodeTemplate -> { replaceNode(csar, topology, nodeTemplate, K8S_TYPES_DEPLOYMENT, K8S_CSAR_VERSION); }); From 750abf5c762fff7115f6ac918beaf087e8162072 Mon Sep 17 00:00:00 2001 From: Albertin Loic Date: Wed, 25 Mar 2020 10:12:24 +0100 Subject: [PATCH 2/2] Fix containers dependencies on multi locations --- .../KubernetesFinalTopologyModifier.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java index 862a094..abc131f 100644 --- a/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java +++ b/src/main/java/org/alien4cloud/plugin/kubernetes/modifier/KubernetesFinalTopologyModifier.java @@ -725,11 +725,28 @@ private void manageContainerDependencies(Csar csar, Topology topology, NodeTempl NormativeRelationshipConstants.DEPENDS_ON, "dependency", "feature"); setNodeTagValue(relationshipTemplate, A4C_KUBERNETES_MODIFIER_TAG + "_created_from", sourceContainerNode.getName() + " -> " + containerNode.getName()); + return; } } } + // else may be a classic node + // Just add link to the controller + RelationshipTemplate relationshipTemplate = addRelationshipTemplate(csar, topology, + sourceContainerNode, controllerResource.getName(), + NormativeRelationshipConstants.DEPENDS_ON, "dependency", "feature"); + setNodeTagValue(relationshipTemplate, A4C_KUBERNETES_MODIFIER_TAG + "_created_from", + sourceContainerNode.getName() + " -> " + containerNode.getName()); }); + // Report dependencies to the controller + Set dependsOn = TopologyNavigationUtil.getTargetNodes(topology, containerNode, "dependency"); + for (NodeTemplate targetNode : dependsOn) { + RelationshipTemplate relationshipTemplate = addRelationshipTemplate(csar, topology, + controllerResource, targetNode.getName(), + NormativeRelationshipConstants.DEPENDS_ON, "dependency", "feature"); + setNodeTagValue(relationshipTemplate, A4C_KUBERNETES_MODIFIER_TAG + "_created_from", + containerNode.getName() + " -> " + targetNode.getName()); + } } private void manageContainer(Csar csar, Topology topology, NodeTemplate containerNode, Map nodeReplacementMap,