Skip to content

Commit

Permalink
Merge pull request #25 from ystia/feature/BRBDCF-973-services-support
Browse files Browse the repository at this point in the history
Feature/brbdcf 973 services support
  • Loading branch information
laurentganne authored May 9, 2018
2 parents a35260b + a6533c0 commit b7c796b
Show file tree
Hide file tree
Showing 49 changed files with 2,506 additions and 117 deletions.
7 changes: 4 additions & 3 deletions data/tosca/normative-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: tosca-normative-types
template_author: TOSCA TC
template_version: 1.0.0
metadata:
template_name: tosca-normative-types
template_author: TOSCA TC
template_version: 1.0.0

description: >
Contains the normative types definition as currently supported in yorc.
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-aws-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-aws-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-aws-types
template_author: yorc
template_version: 1.0.0

imports:
- yorc: <yorc-types.yml>
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-docker-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-docker-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-docker-types
template_author: yorc
template_version: 1.0.0

imports:
- normative: <normative-types.yml>
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-hostspool-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-hostspool-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-hostspool-types
template_author: yorc
template_version: 1.0.0

imports:
- yorc: <yorc-types.yml>
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-kubernetes-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-kubernetes-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-kubernetes-types
template_author: yorc
template_version: 1.0.0

imports:
- normative: <yorc-docker-types.yml>
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-openstack-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-openstack-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-openstack-types
template_author: yorc
template_version: 1.0.0

imports:
- yorc: <yorc-types.yml>
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-slurm-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-slurm-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-slurm-types
template_author: yorc
template_version: 1.0.0

imports:
- yorc: <yorc-types.yml>
Expand Down
7 changes: 4 additions & 3 deletions data/tosca/yorc-types.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
tosca_definitions_version: yorc_tosca_simple_yaml_1_0

template_name: yorc-types
template_author: yorc
template_version: 1.0.0
metadata:
template_name: yorc-types
template_author: yorc
template_version: 1.0.0

imports:
- normative: <normative-types.yml>
Expand Down
86 changes: 84 additions & 2 deletions deployments/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ package deployments
import (
"context"
"path"
"strings"

"github.com/hashicorp/consul/api"
"github.com/pkg/errors"
"github.com/ystia/yorc/helper/consulutil"
"github.com/ystia/yorc/log"
"github.com/ystia/yorc/tosca"
)

// HasScalableCapability check if the given nodeName in the specified deployment, has in this capabilities a Key named scalable
Expand Down Expand Up @@ -211,6 +214,24 @@ func GetInstanceCapabilityAttribute(kv *api.KV, deploymentID, nodeName, instance
}
}

// Capability attributes of a Service referencing an application in another
// deployment are actually available as attributes of the node template
substitutionInstance, err := isSubstitutionNodeInstance(kv, deploymentID, nodeName, instanceName)
if err != nil {
return false, "", err
}
if substitutionInstance {

found, result, err := getSubstitutionInstanceCapabilityAttribute(kv, deploymentID, nodeName, instanceName, capabilityName, attrDataType, attributeName, nestedKeys...)
if err != nil || found {
// If there is an error or attribute was found, returning
// else going back to the generic behavior
return found, result, errors.Wrapf(err,
"Failed to get attribute %q for capability %q on substitutable node %q",
attributeName, capabilityName, nodeName)
}
}

// First look at instance scoped attributes
capAttrPath := path.Join(consulutil.DeploymentKVPrefix, deploymentID, "topology/instances", nodeName, instanceName, "capabilities", capabilityName, "attributes", attributeName)
found, result, err := getValueAssignmentWithDataType(kv, deploymentID, capAttrPath, nodeName, instanceName, "", attrDataType, nestedKeys...)
Expand Down Expand Up @@ -244,22 +265,83 @@ func GetInstanceCapabilityAttribute(kv *api.KV, deploymentID, nodeName, instance

// No default found in type hierarchy
// then traverse HostedOn relationships to find the value
host, err := GetHostedOnNode(kv, deploymentID, nodeName)
host, hostInstance, err := GetHostedOnNodeInstance(kv, deploymentID, nodeName, instanceName)
if err != nil {
return false, "", err
}
if host != "" {
found, result, err = GetInstanceCapabilityAttribute(kv, deploymentID, host, instanceName, capabilityName, attributeName, nestedKeys...)
found, result, err = GetInstanceCapabilityAttribute(kv, deploymentID, host, hostInstance, capabilityName, attributeName, nestedKeys...)
if err != nil || found {
// If there is an error or attribute was found
return found, result, err
}
}

isEndpoint, err := IsTypeDerivedFrom(kv, deploymentID, capabilityType,
tosca.EndpointCapability)
if err != nil {
return false, "", err
}

// TOSCA specification at :
// http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/TOSCA-Simple-Profile-YAML-v1.2.html#DEFN_TYPE_CAPABILITIES_ENDPOINT
// describes that the ip_address attribute of an endpoint is the IP address
// as propagated up by the associated node’s host (Compute) container.
if isEndpoint && attributeName == "ip_address" && host != "" {
found, result, err = getIPAddressFromHost(kv, deploymentID, host,
hostInstance, nodeName, instanceName, capabilityName)
if err != nil || found {
return found, result, err
}
}

// If still not found check properties as the spec states "TOSCA orchestrators will automatically reflect (i.e., make available) any property defined on an entity making it available as an attribute of the entity with the same name as the property."
return GetCapabilityProperty(kv, deploymentID, nodeName, capabilityName, attributeName, nestedKeys...)
}

func getIPAddressFromHost(kv *api.KV, deploymentID, hostName, hostInstance,
nodeName, instanceName, capabilityName string) (bool, string, error) {

// First check the network name in the capability property to find the right
// IP address attribute (default: private address)
ipAddressAttrName := "private_address"

found, netName, err := GetCapabilityProperty(kv, deploymentID, nodeName, capabilityName, "network_name")
if err != nil {
return false, "", err
}

if found && strings.ToLower(netName) == "public" {
ipAddressAttrName = "public_address"
}

found, result, err := GetInstanceAttribute(kv, deploymentID, hostName, hostInstance,
ipAddressAttrName)

if err == nil && found {
log.Debugf("Found IP address %s for %s %s %s %s on network %s from host %s %s",
result, deploymentID, nodeName, instanceName, capabilityName, netName, hostName, hostInstance)
} else {
log.Debugf("Found no IP address for %s %s %s %s on network %s from host %s %s",
deploymentID, nodeName, instanceName, capabilityName, netName, hostName, hostInstance)
}

return found, result, err

}

// GetNodeCapabilityAttributeNames retrieves the names for all capability attributes
// of a capability on a given node name
func GetNodeCapabilityAttributeNames(kv *api.KV, deploymentID, nodeName, capabilityName string, exploreParents bool) ([]string, error) {

capabilityType, err := GetNodeCapabilityType(kv, deploymentID, nodeName, capabilityName)
if err != nil {
return nil, err
}
return GetTypeAttributes(kv, deploymentID, capabilityType, exploreParents)

}

// SetInstanceCapabilityAttribute sets a capability attribute for a given node instance
func SetInstanceCapabilityAttribute(deploymentID, nodeName, instanceName, capabilityName, attributeName, value string) error {
return SetInstanceCapabilityAttributeComplex(deploymentID, nodeName, instanceName, capabilityName, attributeName, value)
Expand Down
15 changes: 15 additions & 0 deletions deployments/consul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ func TestRunConsulDeploymentsPackageTests(t *testing.T) {
t.Run("testImportTopologyTemplate", func(t *testing.T) {
testImportTopologyTemplate(t, kv)
})
t.Run("testTopologyTemplateMetadata", func(t *testing.T) {
testTopologyTemplateMetadata(t, kv)
})
t.Run("testSubstitutionServiceCapabilityMappings", func(t *testing.T) {
testSubstitutionServiceCapabilityMappings(t, kv)
})
t.Run("testSubstitutionServiceRequirementMappings", func(t *testing.T) {
testSubstitutionServiceRequirementMappings(t, kv)
})
t.Run("testSubstitutionClientDirective", func(t *testing.T) {
testSubstitutionClientDirective(t, kv)
})
t.Run("testSubstitutionClientServiceInstance", func(t *testing.T) {
testSubstitutionClientServiceInstance(t, kv)
})
t.Run("TestOperationImplementationArtifact", func(t *testing.T) {
testOperationImplementationArtifact(t, kv)
})
Expand Down
64 changes: 48 additions & 16 deletions deployments/definition_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func storeTopology(ctx context.Context, topology tosca.Topology, deploymentID, t
return ctx.Err()
default:
}
log.Debugf("Storing topology with name %q (Import prefix %q)", topology.Name, importPrefix)
log.Debugf("Storing topology with name %q (Import prefix %q)", topology.Metadata[tosca.TemplateName], importPrefix)
storeTopologyTopLevelKeyNames(ctx, topology, path.Join(topologyPrefix, importPrefix))
if err := storeImports(ctx, topology, deploymentID, topologyPrefix, importPath, rootDefPath); err != nil {
return err
Expand All @@ -120,7 +120,13 @@ func storeTopology(ctx context.Context, topology tosca.Topology, deploymentID, t
if isRootTopologyTemplate {
storeInputs(ctx, topology, topologyPrefix)
storeOutputs(ctx, topology, topologyPrefix)
storeSubstitutionMappings(ctx, topology, topologyPrefix)
storeNodes(ctx, topology, topologyPrefix, importPath, rootDefPath)
} else {
// For imported templates, storing substitution mappings if any
// as they contain details on service to application/node type mapping
storeSubstitutionMappings(ctx, topology,
path.Join(topologyPrefix, importPrefix))
}

if err := storeNodeTypes(ctx, topology, topologyPrefix, importPath); err != nil {
Expand Down Expand Up @@ -150,9 +156,7 @@ func storeTopologyTopLevelKeyNames(ctx context.Context, topology tosca.Topology,
consulStore := ctx.Value(consulStoreKey).(consulutil.ConsulStore)
consulStore.StoreConsulKeyAsString(topologyPrefix+"/tosca_version", topology.TOSCAVersion)
consulStore.StoreConsulKeyAsString(topologyPrefix+"/description", topology.Description)
consulStore.StoreConsulKeyAsString(topologyPrefix+"/name", topology.Name)
consulStore.StoreConsulKeyAsString(topologyPrefix+"/version", topology.Version)
consulStore.StoreConsulKeyAsString(topologyPrefix+"/author", topology.Author)
storeStringMap(consulStore, topologyPrefix+"/metadata", topology.Metadata)
}

//storeRepositories store repositories
Expand Down Expand Up @@ -313,6 +317,11 @@ func storeNodes(ctx context.Context, topology tosca.Topology, topologyPrefix, im
nodePrefix := nodesPrefix + "/" + nodeName
consulStore.StoreConsulKeyAsString(nodePrefix+"/name", nodeName)
consulStore.StoreConsulKeyAsString(nodePrefix+"/type", node.Type)
if node.Directives != nil {
consulStore.StoreConsulKeyAsString(
path.Join(nodePrefix, "directives"),
strings.Join(node.Directives, ","))
}
propertiesPrefix := nodePrefix + "/properties"
for propName, propValue := range node.Properties {
storeValueAssignment(consulStore, propertiesPrefix+"/"+url.QueryEscape(propName), propValue)
Expand Down Expand Up @@ -425,6 +434,22 @@ func storeValueAssignment(consulStore consulutil.ConsulStore, vaPrefix string, v
}
}

func storeMapValueAssignment(consulStore consulutil.ConsulStore, prefix string,
mapValueAssignment map[string]*tosca.ValueAssignment) {

for name, value := range mapValueAssignment {
storeValueAssignment(consulStore, path.Join(prefix, name), value)
}
}

func storeStringMap(consulStore consulutil.ConsulStore, prefix string,
stringMap map[string]string) {

for name, value := range stringMap {
consulStore.StoreConsulKeyAsString(path.Join(prefix, name), value)
}
}

func storeInputDefinition(consulStore consulutil.ConsulStore, inputPrefix, operationOutputPrefix string, inputDef tosca.Input) error {
isValueAssignment := false
isPropertyDefinition := false
Expand Down Expand Up @@ -858,21 +883,28 @@ func enhanceNodes(ctx context.Context, kv *api.KV, deploymentID string) error {
if err != nil {
return err
}
err = createInstancesForNode(ctxStore, kv, deploymentID, nodeName)
if err != nil {
return err
}
err = fixAlienBlockStorages(ctxStore, kv, deploymentID, nodeName)
if err != nil {
return err
}
var isCompute bool
isCompute, err = IsNodeDerivedFrom(kv, deploymentID, nodeName, "tosca.nodes.Compute")

substitutable, err := isSubstitutableNode(kv, deploymentID, nodeName)
if err != nil {
return err
}
if isCompute {
computes = append(computes, nodeName)
if !substitutable {
err = createInstancesForNode(ctxStore, kv, deploymentID, nodeName)
if err != nil {
return err
}
err = fixAlienBlockStorages(ctxStore, kv, deploymentID, nodeName)
if err != nil {
return err
}
var isCompute bool
isCompute, err = IsNodeDerivedFrom(kv, deploymentID, nodeName, "tosca.nodes.Compute")
if err != nil {
return err
}
if isCompute {
computes = append(computes, nodeName)
}
}
}
for _, nodeName := range computes {
Expand Down
Loading

0 comments on commit b7c796b

Please sign in to comment.