* YANG to TOSCA translator 31/1331/1
authorHashir Mohammed <hashir.mohammed@riftio.com>
Wed, 1 Mar 2017 12:42:47 +0000 (07:42 -0500)
committerHashir Mohammed <hashir.mohammed@riftio.com>
Mon, 20 Mar 2017 07:11:46 +0000 (03:11 -0400)
* Bug fixes - TOSCA to YANG

Signed-off-by: Hashir Mohammed <hashir.mohammed@riftio.com>
17 files changed:
common/python/CMakeLists.txt
common/python/rift/mano/tosca_translator/dummy_vnf_node.yaml [new file with mode: 0644]
common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_compute.py
common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_network_network.py
common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_vnf_configuration.py
common/python/rift/mano/tosca_translator/rwmano/translate_node_templates.py
common/python/rift/mano/tosca_translator/test/data/ping_pong_csar_tosca_new_spec.zip [new file with mode: 0644]
common/python/rift/mano/yang_translator/riftiotypes.yaml [new file with mode: 0644]
common/python/rift/mano/yang_translator/rwmano/syntax/tosca_resource.py
common/python/rift/mano/yang_translator/rwmano/syntax/tosca_template.py
common/python/rift/mano/yang_translator/rwmano/translate_descriptors.py
common/python/rift/mano/yang_translator/rwmano/yang/yang_nsd.py
common/python/rift/mano/yang_translator/rwmano/yang/yang_vdu.py
common/python/rift/mano/yang_translator/rwmano/yang/yang_vnfd.py
common/python/rift/mano/yang_translator/rwmano/yang_translator.py
rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/export.py
rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/tosca.py

index 22018c3..50ed1de 100644 (file)
@@ -112,6 +112,10 @@ rift_python_install_tree(
     rift/mano/tosca_translator/rwmano/tosca/tosca_compute.py
     rift/mano/tosca_translator/rwmano/tosca/tosca_scaling_group.py
     rift/mano/tosca_translator/rwmano/tosca/tosca_initial_config.py
+    rift/mano/tosca_translator/rwmano/tosca/tosca_placement_group.py
+    rift/mano/tosca_translator/rwmano/tosca/tosca_vnf_configuration.py
+    rift/mano/tosca_translator/rwmano/tosca/tosca_forwarding_graph.py
+    rift/mano/tosca_translator/rwmano/tosca/tosca_forwarding_path.py
     rift/mano/tosca_translator/common/__init__.py
     rift/mano/tosca_translator/common/utils.py
     rift/mano/tosca_translator/common/exception.py
@@ -167,6 +171,20 @@ set(TRANSLATOR_SCRIPTS
   ${CMAKE_CURRENT_SOURCE_DIR}/rift/mano/tosca_translator/tosca-translator
   ${CMAKE_CURRENT_SOURCE_DIR}/rift/mano/yang_translator/yang-translator)
 
+install(
+  FILES rift/mano/yang_translator/riftiotypes.yaml
+    DESTINATION
+      usr/rift/mano/common
+    COMPONENT ${PKG_LONG_NAME}
+    )
+
+install(
+  FILES rift/mano/tosca_translator/dummy_vnf_node.yaml
+    DESTINATION
+      usr/rift/mano/common
+    COMPONENT ${PKG_LONG_NAME}
+    )
+
 install(
   FILES ${TRANSLATOR_SCRIPTS}
     DESTINATION
diff --git a/common/python/rift/mano/tosca_translator/dummy_vnf_node.yaml b/common/python/rift/mano/tosca_translator/dummy_vnf_node.yaml
new file mode 100644 (file)
index 0000000..6798e2a
--- /dev/null
@@ -0,0 +1,1496 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0
+description: Toy NS
+data_types:
+  tosca.datatypes.nfv.riftio.dashboard_params:
+    properties:
+      path:
+        type: string
+        description: >-
+          The HTTP path for the dashboard
+      port:
+        type: tosca.datatypes.network.PortDef
+        description: >-
+          The HTTP port for the dashboard
+        default: 80
+      https:
+        type: boolean
+        description: >-
+          Pick HTTPS instead of HTTP , Default is false
+        default: false
+        required: false
+  tosca.datatypes.nfv.riftio.monitoring_param_ui:
+    properties:
+      description:
+        type: string
+        required: false
+      group_tag:
+        type: string
+        description: >-
+          A simple tag to group monitoring parameters
+        required: false
+      widget_type:
+        type: string
+        description: >-
+          Type of the widget
+        default: counter
+        constraints:
+          - valid_values:
+              - histogram
+              - bar
+              - gauge
+              - slider
+              - counter
+              - textbox
+      units:
+        type: string
+        required: false
+  tosca.datatypes.nfv.riftio.monitoring_param_value:
+    properties:
+      value_type:
+        type: string
+        default: integer
+        constraints:
+          - valid_values:
+              - integer
+              - float
+              - string
+      numeric_min:
+        type: integer
+        description: >-
+          Minimum value for the parameter
+        required: false
+      numeric_max:
+        type: integer
+        description: >-
+          Maxium value for the parameter
+        required: false
+      string_min:
+        type: integer
+        description: >-
+          Minimum string length for the parameter
+        required: false
+        constraints:
+          - greater_or_equal: 0
+      string_max:
+        type: integer
+        description: >-
+          Maximum string length for the parameter
+        required: false
+        constraints:
+          - greater_or_equal: 0
+  tosca.datatypes.compute.Container.Architecture.CPUAllocation:
+    derived_from: tosca.datatypes.Root
+    properties:
+      cpu_affinity:
+        type: string
+        required: false
+        constraints:
+          - valid_values: [shared, dedicated, any]
+      thread_allocation:
+        type: string
+        required: false
+        constraints:
+          - valid_values: [avoid, separate, isolate, prefer]
+      socket_count:
+        type: integer
+        required: false
+      core_count:
+        type: integer
+        required: false
+      thread_count:
+        type: integer
+        required: false
+
+  tosca.datatypes.compute.Container.Architecture.NUMA:
+    derived_from: tosca.datatypes.Root
+    properties:
+      id:
+        type: integer
+        constraints:
+          - greater_or_equal: 0
+      vcpus:
+        type: list
+        entry_schema:
+          type: integer
+          constraints:
+            -  greater_or_equal: 0
+      mem_size:
+        type: scalar-unit.size
+        constraints:
+          - greater_or_equal: 0 MB
+  tosca.datatypes.nfv.riftio.paired_thread_map:
+    properties:
+      thread_a:
+        type: integer
+        required: true
+        constraints:
+          - greater_or_equal: 0
+      thread_b:
+        type: integer
+        required: true
+        constraints:
+          - greater_or_equal: 0
+
+  tosca.datatypes.nfv.riftio.paired_threads:
+    properties:
+      num_paired_threads:
+        type: integer
+        constraints:
+          - greater_or_equal: 1
+      paired_thread_ids:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.riftio.paired_thread_map
+        constraints:
+          - max_length: 16
+        required: false
+
+  tosca.datatypes.compute.riftio.numa:
+    properties:
+      id:
+        type: integer
+        constraints:
+          - greater_or_equal: 0
+      vcpus:
+        type: list
+        entry_schema:
+          type: integer
+          constraints:
+            -  greater_or_equal: 0
+        required: false
+      mem_size:
+        type: scalar-unit.size
+        constraints:
+          - greater_or_equal: 0 MB
+        required: false
+      om_numa_type:
+        type: string
+        description: Openmano Numa type selection
+        constraints:
+          - valid_values: [cores, paired-threads, threads]
+        required: false
+      num_cores:
+        type: integer
+        description: Use when om_numa_type is cores
+        constraints:
+          - greater_or_equal: 1
+        required: false
+      paired_threads:
+        type: tosca.datatypes.nfv.riftio.paired_threads
+        description: Use when om_numa_type is paired-threads
+        required: false
+      num_threads:
+        type: integer
+        description: Use when om_numa_type is threads
+        constraints:
+          - greater_or_equal: 1
+        required: false
+  
+  tosca.nfv.datatypes.pathType:
+    properties:
+      forwarder:
+        type: string
+        required: true
+      capability:
+        type: string
+        required: true
+
+  tosca.nfv.datatypes.aclType:
+    properties:
+      eth_type:
+        type: string
+        required: false
+      eth_src:
+        type: string
+        required: false
+      eth_dst:
+        type: string
+        required: false
+      vlan_id:
+        type: integer
+        constraints:
+          - in_range: [ 1, 4094 ]
+        required: false
+      vlan_pcp:
+        type: integer
+        constraints:
+          - in_range: [ 0, 7 ]
+        required: false
+      mpls_label:
+        type: integer
+        constraints:
+          - in_range: [ 16, 1048575]
+        required: false
+      mpls_tc:
+        type: integer
+        constraints:
+          - in_range: [ 0, 7 ]
+        required: false
+      ip_dscp:
+        type: integer
+        constraints:
+          - in_range: [ 0, 63 ]
+        required: false
+      ip_ecn:
+        type: integer
+        constraints:
+          - in_range: [ 0, 3 ]
+        required: false
+      ip_src_prefix:
+        type: string
+        required: false
+      ip_dst_prefix:
+        type: string
+        required: false
+      ip_proto:
+        type: integer
+        constraints:
+          - in_range: [ 1, 254 ]
+        required: false
+      destination_port_range:
+        type: string
+        required: false
+      source_port_range:
+        type: string
+        required: false
+      network_src_port_id:
+        type: string
+        required: false
+      network_dst_port_id:
+        type: string
+        required: false
+      network_id:
+        type: string
+        required: false
+      network_name:
+        type: string
+        required: false
+      tenant_id:
+        type: string
+        required: false
+      icmpv4_type:
+        type: integer
+        constraints:
+          - in_range: [ 0, 254 ]
+        required: false
+      icmpv4_code:
+        type: integer
+        constraints:
+          - in_range: [ 0, 15 ]
+        required: false
+      arp_op:
+        type: integer
+        constraints:
+          - in_range: [ 1, 25 ]
+        required: false
+      arp_spa:
+        type: string
+        required: false
+      arp_tpa:
+        type: string
+        required: false
+      arp_sha:
+        type: string
+        required: false
+      arp_tha:
+        type: string
+        required: false
+      ipv6_src:
+        type: string
+        required: false
+      ipv6_dst:
+        type: string
+        required: false
+      ipv6_flabel:
+        type: integer
+        constraints:
+          - in_range: [ 0, 1048575]
+        required: false
+      icmpv6_type:
+        type: integer
+        constraints:
+          - in_range: [ 0, 255]
+        required: false
+      icmpv6_code:
+        type: integer
+        constraints:
+          - in_range: [ 0, 7]
+        required: false
+      ipv6_nd_target:
+        type: string
+        required: false
+      ipv6_nd_sll:
+        type: string
+        required: false
+      ipv6_nd_tll:
+        type: string
+        required: false
+
+  
+  tosca.datatypes.nfv.riftio.vnf_configuration:
+    properties:
+      config_type:
+        type: string
+        description: >-
+          Type of the configuration agent to use
+        constraints:
+          - valid_values: [script, netconf, rest, juju]
+      config_details:
+        type: map
+        description: >-
+          Specify the details for the config agent, like
+          script type, juju charm to use, etc.
+      config_template:
+        required: false
+        type: string
+      config_delay:
+        type: integer
+        constraints:
+        - greater_or_equal: 0
+        default: 0
+        required: false
+      config_priority:
+        type: integer
+        constraints:
+        - greater_than: 0
+
+  tosca.datatypes.nfv.riftio.parameter_value:
+    properties:
+      name:
+        type: string
+        description: Name of the parameter
+      value:
+        type: string
+        description: Value of the parameter
+
+  tosca.datatypes.nfv.riftio.config_primitive:
+    properties:
+      name:
+        type: string
+      seq:
+        type: integer
+        description: >-
+          Order in which to apply, when multiple ones are defined
+        default: 0
+        constraints:
+          - greater_or_equal: 0
+      parameter:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.riftio.parameter_value
+      user_defined_script:
+        type: string
+  tosca.datatypes.nfv.riftio.primitive_parameter:
+    properties:
+      data_type:
+        type: string
+        description: >-
+          Data type associated with the name
+        constraints:
+          - valid_values: [string, integer, boolean]
+      mandatory:
+        type: boolean
+        description: >-
+          If this field is mandatory
+        default: false
+        required: false
+      default_value:
+        type: string
+        description: >-
+          The default value for this field
+        required: false
+      parameter_pool:
+        type: string
+        description: >-
+          Parameter pool name to use for this parameter
+        required: false
+      read_only:
+        type: boolean
+        description: >-
+          The value should be greyed out by the UI.
+          Only applies to parameters with default values.
+        required: false
+        default: false
+      hidden:
+        type: boolean
+        description: >-
+          The field should be hidden by the UI.
+          Only applies to parameters with default values.
+        required: false
+        default: false
+  tosca.datatypes.nfv.riftio.primitive_parameter_group:
+    properties:
+      name:
+        type: string
+        description: >-
+          Name of the parameter group
+      mandatory:
+        type: boolean
+        description: >-
+          If this group is mandatory
+        default: false
+        required: false
+      parameter:
+        type: map
+        description: >-
+          List of parameters for the service primitive
+        entry_schema: osca.datatypes.riftio.primitive_parameter
+
+  tosca.datatypes.nfv.riftio.vnf_primitive_group:
+    properties:
+      vnf_name:
+        type: string
+        description: >-
+          Name of the VNF in the NS
+      primitive:
+        type: map
+        entry_schema:
+          type: string
+        description: >-
+          Index and name of the primitive
+
+
+capability_types:
+  tosca.capabilities.nfv.riftio.mgmt_interface:
+    derived_from: tosca.capabilities.Endpoint
+    properties:
+      static_ip:
+        type: string
+        required: false
+        description: >-
+          Specifies the static IP address for managing the VNF
+      connection_point:
+        type: string
+        required: false
+        description: >-
+          Use the ip address associated with this connection point
+      dashboard_params:
+        type: tosca.datatypes.nfv.riftio.dashboard_params
+        required: false
+        description: >-
+          Parameters for the VNF dashboard
+  tosca.capabilities.nfv.riftio.monitoring_param:
+    derived_from: tosca.capabilities.nfv.Metric
+    properties:
+      name:
+        type: string
+        required: false
+      description:
+        type: string
+        required: false
+      protocol:
+        type: string
+        default: http
+        constraints:
+          - equal: http
+      polling_interval:
+        type: scalar-unit.time
+        description: >-
+          The HTTP polling interval in seconds
+        default: 2 s
+      username:
+        type: string
+        description: >-
+          The HTTP basic auth username
+        required: false
+      password:
+        type: string
+        description: >-
+          The HTTP basic auth password
+        required: false
+      method:
+        type: string
+        description: >-
+          This is the method to be performed at the uri.
+          GET by default for action
+        default: get
+        constraints:
+          - valid_values: [post, put, get, delete, options, patch]
+      headers:
+        type: map
+        entry_schema:
+          type: string
+        description: >-
+          Custom HTTP headers to put on HTTP request
+        required: false
+      json_query_method:
+        type: string
+        description: >-
+          The method to extract a value from a JSON response
+            namekey    - Use the name as the key for a non-nested value.
+            jsonpath   - Use jsonpath-rw implemenation to extract a value.
+            objectpath - Use objectpath implemenation to extract a value.
+        constraints:
+          - valid_values: [namekey, jsonpath, objectpath]
+        default: namekey
+      json_query_path:
+        type: string
+        description: >-
+          The json path to use to extract value from JSON structure
+        required: false
+      json_object_path:
+        type: string
+        description: >-
+          The object path to use to extract value from JSON structure
+        required: false
+      ui_data:
+        type: tosca.datatypes.nfv.riftio.monitoring_param_ui
+        required: false
+      constraints:
+        type: tosca.datatypes.nfv.riftio.monitoring_param_value
+        required: false
+  tosca.capabilities.nfv.riftio.numa_extension:
+    derived_from: tosca.capabilities.Root
+    properties:
+      node_cnt:
+        type: integer
+        description: >-
+          The number of numa nodes to expose to the VM
+        constraints:
+          - greater_or_equal: 0
+      mem_policy:
+        type: string
+        description: >-
+          This policy specifies how the memory should
+                   be allocated in a multi-node scenario.
+                   STRICT    - The memory must be allocated
+                               strictly from the memory attached
+                               to the NUMA node.
+                   PREFERRED - The memory should be allocated
+                               preferentially from the memory
+                               attached to the NUMA node
+        constraints:
+          - valid_values: [strict, preferred, STRICT, PREFERRED]
+      node:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.compute.riftio.numa
+  tosca.capabilities.nfv.riftio.vswitch_epa:
+    derived_from: tosca.capabilities.Root
+    properties:
+      ovs_acceleration:
+        type: string
+        description: |-
+          Specifies Open vSwitch acceleration mode.
+             MANDATORY - OVS acceleration is required
+             PREFERRED - OVS acceleration is preferred
+        constraints:
+          - valid_values: [mandatory, preferred, disabled, MANDATORY, PREFERRED, DISABLED]
+      ovs_offload:
+        type: string
+        description: |-
+          Specifies Open vSwitch hardware offload mode.
+             MANDATORY - OVS offload is required
+             PREFERRED - OVS offload is preferred
+        constraints:
+          - valid_values: [mandatory, preferred, disabled, MANDATORY, PREFERRED, DISABLED]
+
+  tosca.capabilities.nfv.riftio.hypervisor_epa:
+    derived_from: tosca.capabilities.Root
+    properties:
+      type:
+        type: string
+        description: |-
+          Specifies the type of hypervisor.
+        constraints:
+          - valid_values: [prefer_kvm, require_kvm, PREFER_KVM, REQUIRE_KVM]
+      version:
+        type: string
+
+  tosca.capabilities.nfv.riftio.host_epa:
+    derived_from: tosca.capabilities.Root
+    properties:
+      cpu_model:
+        type: string
+        description: >-
+          Host CPU model. Examples include SandyBridge,
+          IvyBridge, etc.
+        required: false
+        constraints:
+          - valid_values:
+              - prefer_westmere
+              - require_westmere
+              - prefer_sandbridge
+              - require_sandybridge
+              - prefer_ivybridge
+              - require_ivybridge
+              - prefer_haswell
+              - require_haswell
+              - prefer_broadwell
+              - require_broadwell
+              - prefer_nehalem
+              - require_nehalem
+              - prefer_penryn
+              - require_penryn
+              - prefer_conroe
+              - require_conroe
+              - prefer_core2duo
+              - require_core2duo
+              - PREFER_WESTMERE
+              - REQUIRE_WESTMERE
+              - PREFER_SANDBRIDGE
+              - REQUIRE_SANDYBRIDGE
+              - PREFER_IVYBRIDGE
+              - REQUIRE_IVYBRIDGE
+              - PREFER_HASWELL
+              - REQUIRE_HASWELL
+              - PREFER_BROADWELL
+              - REQUIRE_BROADWELL
+              - PREFER_NEHALEM
+              - REQUIRE_NEHALEM
+              - PREFER_PENRYN
+              - REQUIRE_PENRYN
+              - PREFER_CONROE
+              - REQUIRE_CONROE
+              - PREFER_CORE2DUO
+              - REQUIRE_CORE2DUO
+      cpu_arch:
+        type: string
+        description: >-
+          Host CPU architecture
+        required: false
+        constraints:
+          - valid_values:
+              - prefer_x86
+              - require_x86
+              - prefer_x86_64
+              - require_x86_64
+              - prefer_i686
+              - require_i686
+              - prefer_ia64
+              - require_ia64
+              - prefer_armv7
+              - require_armv7
+              - prefer_armv8
+              - require_armv8
+              - PREFER_X86
+              - REQUIRE_X86
+              - PREFER_X86_64
+              - REQUIRE_X86_64
+              - PREFER_I686
+              - REQUIRE_I686
+              - PREFER_IA64
+              - REQUIRE_IA64
+              - PREFER_ARMV7
+              - REQUIRE_ARMV7
+              - PREFER_ARMV8
+              - REQUIRE_ARMV8
+      cpu_vendor:
+        type: string
+        description: >-
+          Host CPU vendor
+        required: false
+        constraints:
+          - valid_values:
+              - prefer_intel
+              - require_intel
+              - prefer_amd
+              - requie_amd
+              - PREFER_INTEL
+              - REQUIRE_INTEL
+              - PREFER_AMD
+              - REQUIE_AMD
+      cpu_socket_count:
+        type: integer
+        description: >-
+          Number of sockets on the host
+        required: false
+        constraints:
+          - greater_than : 0
+      cpu_core_count:
+        type: integer
+        description: >-
+          Number of cores on the host
+        required: false
+        constraints:
+          - greater_than : 0
+      cpu_core_thread_count:
+        type: integer
+        description: >-
+          Number of threads per core on the host
+        required: false
+        constraints:
+          - greater_than : 0
+      cpu_feature:
+        type: list
+        entry_schema:
+          type: string
+        description: |-
+          Enumeration for CPU features.
+
+          AES- CPU supports advanced instruction set for
+          AES (Advanced Encryption Standard).
+
+          CAT- Cache Allocation Technology (CAT) allows
+          an Operating System, Hypervisor, or similar
+          system management agent to specify the amount
+          of L3 cache (currently the last-level cache
+          in most server and client platforms) space an
+          application can fill (as a hint to hardware
+          functionality, certain features such as power
+          management may override CAT settings).
+
+          CMT- Cache Monitoring Technology (CMT) allows
+          an Operating System, Hypervisor, or similar
+          system management agent to determine the
+          usage of cache based on applications running
+          on the platform. The implementation is
+          directed at L3 cache monitoring (currently
+          the last-level cache in most server and
+          client platforms).
+
+          DDIO- Intel Data Direct I/O (DDIO) enables
+          Ethernet server NICs and controllers talk
+          directly to the processor cache without a
+          detour via system memory. This enumeration
+          specifies if the VM requires a DDIO
+          capable host.
+        required: false
+        constraints:
+          -valid_values:
+            - prefer_aes
+            - require_aes
+            - prefer_cat
+            - require_cat
+            - prefer_cmt
+            - require_cmt
+            - prefer_ddio
+            - require_ddio
+            - prefer_vme
+            - require_vme
+            - prefer_de
+            - require_de
+            - prefer_pse
+            - require_pse
+            - prefer_tsc
+            - require_tsc
+            - prefer_msr
+            - require_msr
+            - prefer_pae
+            - require_pae
+            - prefer_mce
+            - require_mce
+            - prefer_cx8
+            - require_cx8
+            - prefer_apic
+            - require_apic
+            - prefer_sep
+            - require_sep
+            - prefer_mtrr
+            - require_mtrr
+            - prefer_pge
+            - require_pge
+            - prefer_mca
+            - require_mca
+            - prefer_cmov
+            - require_cmov
+            - prefer_pat
+            - require_pat
+            - prefer_pse36
+            - require_pse36
+            - prefer_clflush
+            - require_clflush
+            - prefer_dts
+            - require_dts
+            - prefer_acpi
+            - require_acpi
+            - prefer_mmx
+            - require_mmx
+            - prefer_fxsr
+            - require_fxsr
+            - prefer_sse
+            - require_sse
+            - prefer_sse2
+            - require_sse2
+            - prefer_ss
+            - require_ss
+            - prefer_ht
+            - require_ht
+            - prefer_tm
+            - require_tm
+            - prefer_ia64
+            - require_ia64
+            - prefer_pbe
+            - require_pbe
+            - prefer_rdtscp
+            - require_rdtscp
+            - prefer_pni
+            - require_pni
+            - prefer_pclmulqdq
+            - require_pclmulqdq
+            - prefer_dtes64
+            - require_dtes64
+            - prefer_monitor
+            - require_monitor
+            - prefer_ds_cpl
+            - require_ds_cpl
+            - prefer_vmx
+            - require_vmx
+            - prefer_smx
+            - require_smx
+            - prefer_est
+            - require_est
+            - prefer_tm2
+            - require_tm2
+            - prefer_ssse3
+            - require_ssse3
+            - prefer_cid
+            - require_cid
+            - prefer_fma
+            - require_fma
+            - prefer_cx16
+            - require_cx16
+            - prefer_xtpr
+            - require_xtpr
+            - prefer_pdcm
+            - require_pdcm
+            - prefer_pcid
+            - require_pcid
+            - prefer_dca
+            - require_dca
+            - prefer_sse4_1
+            - require_sse4_1
+            - prefer_sse4_2
+            - require_sse4_2
+            - prefer_x2apic
+            - require_x2apic
+            - prefer_movbe
+            - require_movbe
+            - prefer_popcnt
+            - require_popcnt
+            - prefer_tsc_deadline_timer
+            - require_tsc_deadline_timer
+            - prefer_xsave
+            - require_xsave
+            - prefer_avx
+            - require_avx
+            - prefer_f16c
+            - require_f16c
+            - prefer_rdrand
+            - require_rdrand
+            - prefer_fsgsbase
+            - require_fsgsbase
+            - prefer_bmi1
+            - require_bmi1
+            - prefer_hle
+            - require_hle
+            - prefer_avx2
+            - require_avx2
+            - prefer_smep
+            - require_smep
+            - prefer_bmi2
+            - require_bmi2
+            - prefer_erms
+            - require_erms
+            - prefer_invpcid
+            - require_invpcid
+            - prefer_rtm
+            - require_rtm
+            - prefer_mpx
+            - require_mpx
+            - prefer_rdseed
+            - require_rdseed
+            - prefer_adx
+            - require_adx
+            - prefer_smap
+            - require_smap
+            - PREFER_AES
+            - REQUIRE_AES
+            - PREFER_CAT
+            - REQUIRE_CAT
+            - PREFER_CMT
+            - REQUIRE_CMT
+            - PREFER_DDIO
+            - REQUIRE_DDIO
+            - PREFER_VME
+            - REQUIRE_VME
+            - PREFER_DE
+            - REQUIRE_DE
+            - PREFER_PSE
+            - REQUIRE_PSE
+            - PREFER_TSC
+            - REQUIRE_TSC
+            - PREFER_MSR
+            - REQUIRE_MSR
+            - PREFER_PAE
+            - REQUIRE_PAE
+            - PREFER_MCE
+            - REQUIRE_MCE
+            - PREFER_CX8
+            - REQUIRE_CX8
+            - PREFER_APIC
+            - REQUIRE_APIC
+            - PREFER_SEP
+            - REQUIRE_SEP
+            - PREFER_MTRR
+            - REQUIRE_MTRR
+            - PREFER_PGE
+            - REQUIRE_PGE
+            - PREFER_MCA
+            - REQUIRE_MCA
+            - PREFER_CMOV
+            - REQUIRE_CMOV
+            - PREFER_PAT
+            - REQUIRE_PAT
+            - PREFER_PSE36
+            - REQUIRE_PSE36
+            - PREFER_CLFLUSH
+            - REQUIRE_CLFLUSH
+            - PREFER_DTS
+            - REQUIRE_DTS
+            - PREFER_ACPI
+            - REQUIRE_ACPI
+            - PREFER_MMX
+            - REQUIRE_MMX
+            - PREFER_FXSR
+            - REQUIRE_FXSR
+            - PREFER_SSE
+            - REQUIRE_SSE
+            - PREFER_SSE2
+            - REQUIRE_SSE2
+            - PREFER_SS
+            - REQUIRE_SS
+            - PREFER_HT
+            - REQUIRE_HT
+            - PREFER_TM
+            - REQUIRE_TM
+            - PREFER_IA64
+            - REQUIRE_IA64
+            - PREFER_PBE
+            - REQUIRE_PBE
+            - PREFER_RDTSCP
+            - REQUIRE_RDTSCP
+            - PREFER_PNI
+            - REQUIRE_PNI
+            - PREFER_PCLMULQDQ
+            - REQUIRE_PCLMULQDQ
+            - PREFER_DTES64
+            - REQUIRE_DTES64
+            - PREFER_MONITOR
+            - REQUIRE_MONITOR
+            - PREFER_DS_CPL
+            - REQUIRE_DS_CPL
+            - PREFER_VMX
+            - REQUIRE_VMX
+            - PREFER_SMX
+            - REQUIRE_SMX
+            - PREFER_EST
+            - REQUIRE_EST
+            - PREFER_TM2
+            - REQUIRE_TM2
+            - PREFER_SSSE3
+            - REQUIRE_SSSE3
+            - PREFER_CID
+            - REQUIRE_CID
+            - PREFER_FMA
+            - REQUIRE_FMA
+            - PREFER_CX16
+            - REQUIRE_CX16
+            - PREFER_XTPR
+            - REQUIRE_XTPR
+            - PREFER_PDCM
+            - REQUIRE_PDCM
+            - PREFER_PCID
+            - REQUIRE_PCID
+            - PREFER_DCA
+            - REQUIRE_DCA
+            - PREFER_SSE4_1
+            - REQUIRE_SSE4_1
+            - PREFER_SSE4_2
+            - REQUIRE_SSE4_2
+            - PREFER_X2APIC
+            - REQUIRE_X2APIC
+            - PREFER_MOVBE
+            - REQUIRE_MOVBE
+            - PREFER_POPCNT
+            - REQUIRE_POPCNT
+            - PREFER_TSC_DEADLINE_TIMER
+            - REQUIRE_TSC_DEADLINE_TIMER
+            - PREFER_XSAVE
+            - REQUIRE_XSAVE
+            - PREFER_AVX
+            - REQUIRE_AVX
+            - PREFER_F16C
+            - REQUIRE_F16C
+            - PREFER_RDRAND
+            - REQUIRE_RDRAND
+            - PREFER_FSGSBASE
+            - REQUIRE_FSGSBASE
+            - PREFER_BMI1
+            - REQUIRE_BMI1
+            - PREFER_HLE
+            - REQUIRE_HLE
+            - PREFER_AVX2
+            - REQUIRE_AVX2
+            - PREFER_SMEP
+            - REQUIRE_SMEP
+            - PREFER_BMI2
+            - REQUIRE_BMI2
+            - PREFER_ERMS
+            - REQUIRE_ERMS
+            - PREFER_INVPCID
+            - REQUIRE_INVPCID
+            - PREFER_RTM
+            - REQUIRE_RTM
+            - PREFER_MPX
+            - REQUIRE_MPX
+            - PREFER_RDSEED
+            - REQUIRE_RDSEED
+            - PREFER_ADX
+            - REQUIRE_ADX
+            - PREFER_SMAP
+            - REQUIRE_SMAP
+      om_cpu_model_string:
+        type: string
+        description: >-
+          Openmano CPU model string
+        required: false
+      om_cpu_feature:
+        type: list
+        entry_schema:
+          type: string
+        description: >-
+          List of openmano CPU features
+        required: false
+
+  tosca.capabilities.nfv.riftio.sfc:
+    derived_from: tosca.capabilities.Root
+    description: >-
+      Service Function Chaining support on this VDU
+    properties:
+      sfc_type:
+        type: string
+        description: >-
+          Type of node in Service Function Chaining Architecture
+        constraints:
+          - valid_values: [unaware, classifier, sf, sff, UNAWARE, CLASSIFIER, SF, SFF]
+        default: unaware
+      sf_type:
+        type: string
+        description: >-
+          Type of Service Function.
+             NOTE- This needs to map with Service Function Type in ODL to
+             support VNFFG. Service Function Type is manadatory param in ODL
+             SFC.
+        required: false
+  tosca.capabilities.Compute.Container.Architecture:
+    derived_from: tosca.capabilities.Container
+    properties:
+      mem_page_size:
+        type: string
+        description: >-
+          Memory page allocation size. If a VM requires
+          hugepages, it should choose huge or size_2MB
+          or size_1GB. If the VM prefers hugepages, it
+          should chose prefer_huge.
+             huge         - Require hugepages (either 2MB or 1GB)
+             normal       - Does not require hugepages
+             size_2MB     - Requires 2MB hugepages
+             size_1GB     - Requires 1GB hugepages
+             prefer_huge  - Application perfers hugepages
+          NOTE - huge and normal is only defined in standards as of
+                 now.
+        required: false
+        constraints:
+          - valid_values: [normal, huge, size_2MB, size_1GB, prefer_huge, NORMAL, HUGE, SIZE_2MB, SIZE_1GB, PREFER_HUGE]
+      cpu_allocation:
+        type: tosca.datatypes.compute.Container.Architecture.CPUAllocation
+        required: false
+      numa_nodes:
+        type: map
+        required: false
+        entry_schema:
+          type: tosca.datatypes.compute.Container.Architecture.NUMA
+
+
+node_types:
+  tosca.nodes.nfv.riftio.VDU1:
+    derived_from: tosca.nodes.nfv.VDU
+    properties:
+      description:
+        type: string
+        required: false
+      image:
+        description: >-
+          If an image is specified here, it is assumed that the image
+          is already present in the RO or VIM and not in the package.
+        type: string
+        required: false
+      image_checksum:
+        type: string
+        description: >-
+          Image checksum for the image in RO or VIM.
+        required: false
+      cloud_init:
+        description: >-
+          Inline cloud-init specification
+        required: false
+        type: string
+      count:
+        default: 1
+        type: integer
+    capabilities:
+      virtualLink:
+        type: tosca.capabilities.nfv.VirtualLinkable
+      monitoring_param_1:
+        type: tosca.capabilities.nfv.riftio.monitoring_param
+      mgmt_interface:
+        type: tosca.capabilities.nfv.riftio.mgmt_interface
+      monitoring_param:
+        type: tosca.capabilities.nfv.riftio.monitoring_param
+      numa_extension:
+        type: tosca.capabilities.nfv.riftio.numa_extension
+      vswitch_epa:
+        type: tosca.capabilities.nfv.riftio.vswitch_epa
+      hypervisor_epa:
+        type: tosca.capabilities.nfv.riftio.hypervisor_epa
+      host_epa:
+        type: tosca.capabilities.nfv.riftio.host_epa
+  tosca.nodes.nfv.riftio.CP1:
+    derived_from: tosca.nodes.nfv.CP
+    properties:
+      cp_type:
+        description: Type of the connection point
+        type: string
+        default: VPORT
+        constraints:
+          - valid_values: [VPORT]
+      name:
+        description: Name of the connection point
+        type: string
+        required: false
+      vdu_intf_name:
+        description: Name of the interface on VDU
+        type: string
+      vdu_intf_type:
+        description: >-
+          Specifies the type of virtual interface
+             between VM and host.
+             VIRTIO          - Use the traditional VIRTIO interface.
+             PCI-PASSTHROUGH - Use PCI-PASSTHROUGH interface.
+             SR-IOV          - Use SR-IOV interface.
+             E1000           - Emulate E1000 interface.
+             RTL8139         - Emulate RTL8139 interface.
+             PCNET           - Emulate PCNET interface.
+             OM-MGMT         - Used to specify openmano mgmt external-connection type
+        type: string
+        constraints:
+          - valid_values: [OM-MGMT, VIRTIO, E1000, SR-IOV]
+      bandwidth:
+        type: integer
+        description: Aggregate bandwidth of the NIC
+        constraints:
+          - greater_or_equal: 0
+        required: false
+      vpci:
+        type: string
+        description: >-
+          Specifies the virtual PCI address. Expressed in
+          the following format dddd:dd:dd.d. For example
+          0000:00:12.0. This information can be used to
+          pass as metadata during the VM creation.
+        required: false
+    capabilities:
+      sfc:
+        type: tosca.capabilities.nfv.riftio.sfc
+  tosca.nodes.nfv.riftio.VNF1:
+    derived_from: tosca.nodes.nfv.VNF
+    properties:
+      member_index:
+        type: integer
+        constraints:
+          - greater_or_equal: 1
+        description: Index of the VNF in the NS
+        required: false
+      start_by_default:
+        type: boolean
+        default: true
+        description: Start this VNF on NS instantiate
+      logo:
+        type: string
+        description: >-
+          Logo to display with the VNF in the orchestrator
+        required: false
+    capabilities:      
+      mgmt_interface:
+        type: tosca.capabilities.nfv.riftio.mgmt_interface
+      monitoring_param:
+        type: tosca.capabilities.nfv.riftio.monitoring_param
+      sfc:
+        type: tosca.capabilities.nfv.riftio.sfc
+  tosca.nodes.nfv.riftio.ELAN:
+    derived_from: tosca.nodes.nfv.VL.ELAN
+    properties:
+      description:
+        type: string
+        required: false
+      network_name:
+        type: string
+        description: >-
+          Name of network in VIM account. This is used to indicate
+          pre-provisioned network name in cloud account.
+        required: false
+      root_bandwidth:
+        type: integer
+        description: >-
+          This is the aggregate bandwidth
+        constraints:
+          - greater_or_equal: 0
+        required: false
+      leaf_bandwidth:
+        type: integer
+        description: >-
+          This is the bandwidth of branches
+        constraints:
+          - greater_or_equal: 0
+        required: false
+  tosca.nodes.nfv.riftio.FP1:
+    derived_from: tosca.nodes.nfv.FP
+    properties:
+      id:
+        type: integer
+        required: false
+      policy:
+        type: tosca.nfv.datatypes.policyType
+        required: true
+        description: policy to use to match traffic for this FP
+      path:
+        type: list
+        required: true
+        entry_schema:
+          type: tosca.nfv.datatypes.pathType
+      cp:
+        type: tosca.nfv.datatypes.pathType
+        required: true
+
+
+
+artifact_types:
+  tosca.artifacts.Deployment.riftio.cloud_init_file:
+    derived_from: tosca.artifacts.Deployment
+    file:
+      type: string
+
+  tosca.artifacts.Deployment.Image.riftio.QCOW2:
+    derived_from: tosca.artifacts.Deployment.Image.VM.QCOW2
+    image_checksum:
+      required: false
+      type: string
+
+group_types:
+  tosca.groups.nfv.VNFFG:
+    derived_from: tosca.groups.Root
+    properties:
+      vendor:
+        type: string
+        required: true
+        description: name of the vendor who generate this VNFFG
+      version:
+        type: string
+        required: true
+        description: version of this VNFFG
+      number_of_endpoints:
+        type: integer
+        required: true
+        description: count of the external endpoints included in this VNFFG
+      dependent_virtual_link:
+        type: list
+        entry_schema:
+          type: string
+        required: true
+        description: Reference to a VLD used in this Forwarding Graph
+      connection_point:
+        type: list
+        entry_schema:
+          type: string
+        required: true
+        description: Reference to Connection Points forming the VNFFG
+      constituent_vnfs:
+        type: list
+        entry_schema:
+          type: string
+        required: true
+        description: Reference to a list of VNFD used in this VNF Forwarding Graph
+    members: [ tosca.nodes.nfv.FP ]
+
+  tosca.groups.nfv.riftio.scaling:
+    derived_from: tosca.groups.Root
+    properties:
+      name:
+        type: string
+      min_instances:
+        type: integer
+        description: >-
+          Minimum instances of the scaling group which are allowed.
+          These instances are created by default when the network service
+          is instantiated.
+      max_instances:
+        type: integer
+        description: >-
+          Maximum instances of this scaling group that are allowed
+          in a single network service. The network service scaling
+          will fail, when the number of service group instances
+          exceed the max-instance-count specified.
+      cooldown_time:
+        type: integer
+        description: >-
+          The duration after a scaling-in/scaling-out action has been
+          triggered, for which there will be no further optional
+      ratio:
+        type: map
+        entry_schema:
+          type: integer
+        description: >-
+          Specify the number of instances of each VNF to instantiate
+          for a scaling action
+    members: [tosca.nodes.nfv.VNF]
+    interfaces:
+      action:
+        type: tosca.interfaces.nfv.riftio.scaling.action
+
+interface_types:
+  tosca.interfaces.nfv.riftio.scaling.action:
+    pre_scale_in:
+      description: Operation to execute before a scale in
+    post_scale_in:
+      description: Operation to execute after a scale in
+    pre_scale_out:
+      description: Operation to execute before a scale out
+    post_scale_out:
+      description: Operation to execute after a scale out
+
+policy_types:
+  tosca.policies.nfv.riftio.placement:
+    derived_from: tosca.policies.Placement
+    properties:
+      name:
+        type: string
+        description: >-
+          Place group construct to define the compute resource placement strategy
+          in cloud environment
+      requirement:
+        type: string
+        description: >-
+          This is free text space used to describe the intent/rationale
+          behind this placement group. This is for human consumption only
+      strategy:
+        type: string
+        description: >-
+          Strategy associated with this placement group
+             Following values are possible
+               COLOCATION - Colocation strategy imply intent to share the physical
+                            infrastructure (hypervisor/network) among all members
+                            of this group.
+               ISOLATION - Isolation strategy imply intent to not share the physical
+                           infrastructure (hypervisor/network) among the members
+                           of this group.
+        constraints:
+          valid_values:
+            - COLOCATION
+            - ISOLATION
+  tosca.policies.nfv.riftio.vnf_configuration:
+    derived_from: tosca.policies.Root
+    properties:
+      config:
+        type: tosca.datatypes.nfv.riftio.vnf_configuration
+      initial_config:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.riftio.config_primitive
+  tosca.policies.nfv.riftio.vnf_service_primitives:
+    derived_from: tosca.policies.Root
+    properties:
+      parameter:
+        type: map
+        entry_schema:
+          type: primitive_parameter
+  tosca.policies.nfv.riftio.ns_service_primitives:
+    derived_from: tosca.policies.Root
+    properties:
+      parameter:
+        type: map
+        entry_schema:
+          type: primitive_parameter
+      parameter_group:
+        type: tosca.datatypes.nfv.riftio.primitive_parameter_group
+        description: >-
+          Grouping of parameters which are logically grouped in UI
+        required: false
+      vnf_primitive_group:
+        type: tosca.datatypes.nfv.riftio.vnf_primitive_group
+        description: >-
+          List of service primitives grouped by VNF
+        required: false
+      user_defined_script:
+        type: string
+        description: >-
+          A user defined script
+        required: false
+  tosca.policies.nfv.riftio.initial_config_primitive:
+    derived_from: tosca.policies.Root
+    properties:
+      name:
+        type: string
+      seq:
+        type: integer
+        description: >-
+          Order in which to apply, when multiple ones are defined
+        default: 0
+        constraints:
+          - greater_or_equal: 0
+      parameter:
+        type: map
+        entry_schema:
+          type: string
+      user_defined_script:
+        type: string
+  tosca.policies.nfv.riftio.users:
+    derived_from: tosca.policies.Root
+    description: >-
+      Specify list of public keys to be injected as
+      part of NS instantitation. Use default as entry,
+      to specify the key pairs for default user.
+    properties:
+      user_info:
+        type: string
+        description: >-
+          The user\'s real name
+        required: false
+      key_pairs:
+        type: map
+        description: >-
+          List of public keys for the user
+        entry_schema:
+          type: string
+        required: true
+  tosca.policies.nfv.riftio.dependency:
+    derived_from: tosca.policies.Root
+    description: >-
+      Map dependency between VDUs or VNFs
+    properties:
+      parameter:
+        type: map
+        entry_schema:
+          type: string
+        description: >-
+          Parameter and value for the config
+  tosca.nfv.datatypes.policyType:
+    properties:
+      type:
+        type: string
+        required: false
+        constraints:
+          - valid_values: [ ACL ]
+      criteria:
+        type: list
+        required: true
+        entry_schema:
+          type: tosca.nfv.datatypes.aclType
+topology_template:
+  node_templates:
+    new_vnfd:
+      type: tosca.nodes.nfv.riftio.VNF1
+      properties:
+        id: 2
+        vendor: RIFT.io
+        version: 1.0
index 7bc0bf3..7938485 100755 (executable)
@@ -47,6 +47,16 @@ class ToscaCompute(ManoResource):
     'float':'DECIMAL'
     }
 
+
+    TOSCA_MEM_SIZE = {
+        'huge': 'LARGE',
+        'normal': 'SMALL',
+        'size_2MB': 'SIZE_2MB',
+        'size_1GB': 'SIZE_1GB',
+        'prefer_huge': 'PREFER_LARGE'
+
+    }
+
     def __init__(self, log, nodetemplate, metadata=None):
         super(ToscaCompute, self).__init__(log,
                                            nodetemplate,
@@ -62,6 +72,7 @@ class ToscaCompute(ManoResource):
         self._id = self.name
         self._monitor_param = []
         self._mgmt_interface = {}
+        self._http_endpoint = None
 
     @property
     def image(self):
@@ -207,11 +218,11 @@ class ToscaCompute(ManoResource):
             if 'type' in specs:
                 hypervisor_epa['type'] = specs['type'].upper()
             if 'version' in specs:
-                hypervisor_epa['version'] = specs['version']
+                hypervisor_epa['version'] = str(specs['version'])
 
             return hypervisor_epa
 
-        def get_guest_epa(specs):
+        def get_guest_epa(specs, nfv_comput_specs):
             guest_epa = {}
             guest_epa['numa-node-policy'] = {}
             guest_epa['numa-node-policy']['node'] = []
@@ -230,6 +241,11 @@ class ToscaCompute(ManoResource):
                         else:
                             err_msg = "Specify mem_size of NUMA extension should be in MB"
                             raise ValidationError(message=err_msg)
+                    if 'vcpus' in node:
+                        vcpu_lis =[]
+                        for vcpu in node['vcpus']:
+                            vcpu_lis.append({'id': vcpu})
+                        node_prop['vcpu'] = vcpu_lis
                     if 'om_numa_type' in node:
                         numa_type = node['om_numa_type']
                         if 'paired-threads' == numa_type:
@@ -245,6 +261,16 @@ class ToscaCompute(ManoResource):
                             err_msg = "om_numa_type should be among cores, paired-threads or threads"
                             raise ValidationError(message=err_msg)
                     guest_epa['numa-node-policy']['node'].append(node_prop)
+
+            if 'mem_page_size' in nfv_comput_specs:
+                guest_epa['mempage-size'] = self.TOSCA_MEM_SIZE[nfv_comput_specs['mem_page_size']]
+            if 'cpu_allocation' in nfv_comput_specs:
+                if 'cpu_affinity' in nfv_comput_specs['cpu_allocation']:
+                     guest_epa['cpu-pinning-policy'] = nfv_comput_specs['cpu_allocation']['cpu_affinity'].upper()
+                     guest_epa['trusted-execution'] = False
+                if 'thread_allocation' in nfv_comput_specs['cpu_allocation']:
+                     guest_epa['cpu-thread-pinning-policy'] = nfv_comput_specs['cpu_allocation']['thread_allocation'].upper()
+
             return guest_epa
 
         tosca_caps = self.get_tosca_caps()
@@ -261,13 +287,23 @@ class ToscaCompute(ManoResource):
         if 'vswitch_epa' in tosca_caps:
             self.properties['vswitch-epa'] = get_vswitch_epa(tosca_caps['vswitch_epa'])
         if 'numa_extension' in tosca_caps:
-            self.properties['guest-epa'] = get_guest_epa(tosca_caps['numa_extension'])
+            self.properties['guest-epa'] = get_guest_epa(tosca_caps['numa_extension'], tosca_caps['nfv_compute'])
         if 'monitoring_param' in tosca_caps:
             self._monitor_param.append(get_monitor_param(tosca_caps['monitoring_param'], '1'))
         if 'monitoring_param_1' in tosca_caps:
             self._monitor_param.append(get_monitor_param(tosca_caps['monitoring_param_1'], '2'))
         if 'mgmt_interface' in tosca_caps:
             self._mgmt_interface = get_mgmt_interface(tosca_caps['mgmt_interface'])
+        if len(self._mgmt_interface) > 0:
+            prop = {}
+            if 'dashboard-params' in self._mgmt_interface:
+                if 'path' in self._mgmt_interface['dashboard-params']:
+                    prop['path'] = self._mgmt_interface['dashboard-params']['path']
+                if 'port' in self._mgmt_interface['dashboard-params']:
+                    prop['port'] = self._mgmt_interface['dashboard-params']['port']
+                self._http_endpoint = prop
+
+
 
     def handle_artifacts(self):
         if self.artifacts is None:
@@ -284,9 +320,11 @@ class ToscaCompute(ManoResource):
                         prefix, type_ = value.rsplit('.', 1)
                         if type_ == 'QCOW2':
                             details['type'] = 'qcow2'
+                            self._image = props['file']
                             self.properties['image'] = os.path.basename(props['file'])
                     elif name == 'type' and value == 'tosca.artifacts.Deployment.riftio.cloud_init_file':
                         details['cloud_init_file'] = os.path.basename(props['file'])
+                        self._cloud_init = props['file']
                         self.properties['cloud_init_file'] = os.path.basename(props['file'])
                     elif name == 'file':
                         details['file'] = value
@@ -325,6 +363,7 @@ class ToscaCompute(ManoResource):
         return None
 
     def update_image_checksum(self, in_file):
+
         # Create image checksum
         # in_file is the TOSCA yaml file location
         if self._image is None:
@@ -389,6 +428,8 @@ class ToscaCompute(ManoResource):
         try:
             if len(self._mgmt_interface) > 0:
                 vnfd.mgmt_interface.from_dict(convert_keys_to_python(self._mgmt_interface))
+            if self._http_endpoint:
+                vnfd.http_endpoint.add().from_dict(convert_keys_to_python(self._http_endpoint))
             vnfd.vdu.add().from_dict(props)
         except Exception as e:
             err_msg = _("{0} Exception vdu from dict {1}: {2}"). \
index a2dd92b..a94624d 100644 (file)
@@ -49,6 +49,7 @@ class ToscaNetwork(ManoResource):
             vld_prop['name'] = self.name
             vld_prop['short-name'] = self.name
             vld_prop['type'] = self.get_type()
+            vld_prop['ip_profile_ref'] = "{0}_{1}".format(self.nodetemplate.name, "ip")
             if 'description' in specs:
                 vld_prop['description'] = specs['description']
             if 'vendor' in specs:
@@ -63,13 +64,13 @@ class ToscaNetwork(ManoResource):
                         for mapping in substitution_mapping_list:
                             if req_key in mapping:
                                 # link the VLD to the connection point
-                                node = self.get_node_with_name(mapping[req_key][0], nodes)
+                                node_vld = self.get_node_with_name(mapping[req_key][0], nodes)
                                 if node:
                                     #print()
                                     prop = {}
-                                    prop['member-vnf-index-ref'] = index_count
-                                    prop['vnfd-connection-point-ref'] = node.cp_name
-                                    prop['vnfd-id-ref'] = node.vnf._id
+                                    prop['member-vnf-index-ref'] = node.get_member_vnf_index()
+                                    prop['vnfd-connection-point-ref'] = node_vld.cp_name
+                                    prop['vnfd-id-ref'] = node_vld.vnf._id
                                     vld_connection_point_list.append(prop)
                                     index_count += 1
                 if len(vld_connection_point_list) > 1:
@@ -79,10 +80,8 @@ class ToscaNetwork(ManoResource):
         def get_ip_profile_props(specs):
             ip_profile_prop = {}
             ip_profile_param = {}
-            if 'name' in specs:
-                ip_profile_prop['name'] = specs['name']
-            elif 'description' in specs:
-                ip_profile_prop['name'] = specs['description']
+            if 'ip_profile_ref' in self._vld:
+                ip_profile_prop['name'] = self._vld['ip_profile_ref']
 
             if 'description' in specs:
                 ip_profile_prop['description'] = specs['description']
index 0a54bcc..f90c187 100644 (file)
@@ -44,12 +44,17 @@ class ToscaVnfConfiguration(ManoResource):
         self.properties = {}
         self.linked_to_vnf = True
         self._vnf_name = vnf_name
+        self._vnf_id = None
+        self.scripts = []
 
     def __str__(self):
         return "%s(%s)" % (self.name, self.type)
 
     def handle_properties(self, nodes, groups):
         tosca_props = self.get_policy_props()
+        if self._vnf_name:
+            vnf_node = self.get_node_with_name(self._vnf_name, nodes)
+            self._vnf_id = vnf_node.id
         self.properties["vnf-configuration"] = {}
         prop = {}
         prop["config-attributes"] = {}
@@ -64,6 +69,20 @@ class ToscaVnfConfiguration(ManoResource):
             if 'config_details' in tosca_props['config']:
                 if 'script_type' in tosca_props['config']['config_details']:
                     prop["script"]["script-type"] = tosca_props['config']['config_details']['script_type']
+            if 'initial_config' in tosca_props:
+                prop['initial-config-primitive'] = []
+                #print("Weleek  " + str(tosca_props['initial_config']))
+                for init_config in tosca_props['initial_config']:
+                    if 'parameter' in init_config:
+                        parameters = init_config.pop('parameter')
+                        init_config['parameter'] = []
+                        for key, value in parameters.items():
+                            init_config['parameter'].append({'name': key, 'value': str(value)})
+                            if 'user_defined_script' in init_config:
+                                self.scripts.append('../scripts/{}'. \
+                                format(init_config['user_defined_script']))
+                    prop['initial-config-primitive'].append(init_config)
+
         self.properties = prop
 
     def generate_yang_submodel_gi(self, vnfd):
@@ -86,4 +105,16 @@ class ToscaVnfConfiguration(ManoResource):
                 tosca_props[prop.name] = {'get_param': prop.value.input_name}
             else:
                 tosca_props[prop.name] = prop.value
-        return tosca_props
\ No newline at end of file
+        return tosca_props
+    def get_supporting_files(self, files, desc_id=None):
+        if not len(self.scripts):
+            return
+
+        if self._vnf_id not in files:
+            files[desc_id] = []
+
+        for script in self.scripts:
+            files[self._vnf_id].append({
+                'type': 'script',
+                'name': script,
+            },)
\ No newline at end of file
index 3f74336..2d6c3e1 100644 (file)
@@ -23,6 +23,7 @@ from rift.mano.tosca_translator.common.exception import ToscaClassImportError
 from rift.mano.tosca_translator.common.exception import ToscaModImportError
 from rift.mano.tosca_translator.conf.config import ConfigProvider as translatorConfig
 from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+from toscaparser.tosca_template import ToscaTemplate
 
 
 class TranslateNodeTemplates(object):
@@ -197,6 +198,7 @@ class TranslateNodeTemplates(object):
         vnf_type_substitution_mapping               = {}
         vnf_type_to_capability_substitution_mapping = {}
         tpl = self.tosca.tpl['topology_template']['node_templates']
+        associated_vnfd_flag = False
 
         for node in self.nodetemplates:
             all_node_templates.append(node)
@@ -214,6 +216,7 @@ class TranslateNodeTemplates(object):
             vnf_type_to_capability_substitution_mapping[vnf_type] = []
             vnf_type_to_capability_substitution_mapping[vnf_type] = []
             policies                                              = []
+
             for node in template.nodetemplates:
                 all_node_templates.append(node)
             for node_key in tpl_node:
@@ -226,10 +229,11 @@ class TranslateNodeTemplates(object):
                 policies.append(policy.name)
             for req in template.substitution_mappings.requirements:
                 vnf_type_substitution_mapping[template.substitution_mappings.node_type].append(req)
-            for capability in template.substitution_mappings.capabilities:
-                sub_list = template.substitution_mappings.capabilities[capability]
-                if len(sub_list) > 0:
-                    vnf_type_to_capability_substitution_mapping[vnf_type].append({capability: sub_list[0]})
+            if template.substitution_mappings.capabilities:
+                for capability in template.substitution_mappings.capabilities:
+                    sub_list = template.substitution_mappings.capabilities[capability]
+                    if len(sub_list) > 0:
+                        vnf_type_to_capability_substitution_mapping[vnf_type].append({capability: sub_list[0]})
 
         for node in all_node_templates:
             base_type = ManoResource.get_base_type(node.type_definition)
@@ -245,11 +249,36 @@ class TranslateNodeTemplates(object):
                             metadata=self.metadata)
             # Currently tosca-parser does not add the artifacts
             # to the node
+            if mano_node.type == 'vnfd':
+                associated_vnfd_flag = True
             if mano_node.name in node_to_artifact_map:
                 mano_node.artifacts = node_to_artifact_map[mano_node.name]
             self.mano_resources.append(mano_node)
             self.mano_lookup[node] = mano_node
 
+        if not associated_vnfd_flag:
+            dummy_file = "{0}{1}".format(os.getenv('RIFT_INSTALL'), "/usr/rift/mano/common/dummy_vnf_node.yaml")
+            tosca_vnf = ToscaTemplate(dummy_file, {}, True)
+            vnf_type = self.tosca.topology_template.substitution_mappings.node_type
+            vnf_type_to_vdus_map[vnf_type] = []
+
+            for node in tosca_vnf.nodetemplates:
+                all_node_templates.append(node)
+                base_type = ManoResource.get_base_type(node.type_definition)
+                vnf_type_to_vnf_node[vnf_type] = node.name
+                mano_node = TranslateNodeTemplates. \
+                        TOSCA_TO_MANO_TYPE[base_type.type](
+                            self.log,
+                            node,
+                            metadata=self.metadata)
+                mano_node.vnf_type = vnf_type
+                self.mano_resources.append(mano_node)
+                print("Adding a new node")
+
+            for node in self.tosca.nodetemplates:
+                if 'VDU' in node.type:
+                    vnf_type_to_vdus_map[vnf_type].append(node.name)
+
         # The parser currently do not generate the objects for groups
         for group in self.tosca.topology_template.groups:
             group_type = group.type
diff --git a/common/python/rift/mano/tosca_translator/test/data/ping_pong_csar_tosca_new_spec.zip b/common/python/rift/mano/tosca_translator/test/data/ping_pong_csar_tosca_new_spec.zip
new file mode 100644 (file)
index 0000000..a755040
Binary files /dev/null and b/common/python/rift/mano/tosca_translator/test/data/ping_pong_csar_tosca_new_spec.zip differ
diff --git a/common/python/rift/mano/yang_translator/riftiotypes.yaml b/common/python/rift/mano/yang_translator/riftiotypes.yaml
new file mode 100644 (file)
index 0000000..2fea0e3
--- /dev/null
@@ -0,0 +1,1493 @@
+tosca_definitions_version: tosca_simple_profile_for_nfv_1_0
+description: Extended types
+
+
+data_types:
+  tosca.datatypes.nfv.riftio.dashboard_params:
+    properties:
+      path:
+        type: string
+        description: >-
+          The HTTP path for the dashboard
+      port:
+        type: tosca.datatypes.network.PortDef
+        description: >-
+          The HTTP port for the dashboard
+        default: 80
+      https:
+        type: boolean
+        description: >-
+          Pick HTTPS instead of HTTP , Default is false
+        default: false
+        required: false
+  tosca.datatypes.nfv.riftio.monitoring_param_ui:
+    properties:
+      description:
+        type: string
+        required: false
+      group_tag:
+        type: string
+        description: >-
+          A simple tag to group monitoring parameters
+        required: false
+      widget_type:
+        type: string
+        description: >-
+          Type of the widget
+        default: counter
+        constraints:
+          - valid_values:
+              - histogram
+              - bar
+              - gauge
+              - slider
+              - counter
+              - textbox
+      units:
+        type: string
+        required: false
+  tosca.datatypes.nfv.riftio.monitoring_param_value:
+    properties:
+      value_type:
+        type: string
+        default: integer
+        constraints:
+          - valid_values:
+              - integer
+              - float
+              - string
+      numeric_min:
+        type: integer
+        description: >-
+          Minimum value for the parameter
+        required: false
+      numeric_max:
+        type: integer
+        description: >-
+          Maxium value for the parameter
+        required: false
+      string_min:
+        type: integer
+        description: >-
+          Minimum string length for the parameter
+        required: false
+        constraints:
+          - greater_or_equal: 0
+      string_max:
+        type: integer
+        description: >-
+          Maximum string length for the parameter
+        required: false
+        constraints:
+          - greater_or_equal: 0
+  tosca.datatypes.compute.Container.Architecture.CPUAllocation:
+    derived_from: tosca.datatypes.Root
+    properties:
+      cpu_affinity:
+        type: string
+        required: false
+        constraints:
+          - valid_values: [shared, dedicated, any]
+      thread_allocation:
+        type: string
+        required: false
+        constraints:
+          - valid_values: [avoid, separate, isolate, prefer]
+      socket_count:
+        type: integer
+        required: false
+      core_count:
+        type: integer
+        required: false
+      thread_count:
+        type: integer
+        required: false
+
+  tosca.datatypes.compute.Container.Architecture.NUMA:
+    derived_from: tosca.datatypes.Root
+    properties:
+      id:
+        type: integer
+        constraints:
+          - greater_or_equal: 0
+      vcpus:
+        type: list
+        entry_schema:
+          type: integer
+          constraints:
+            -  greater_or_equal: 0
+      mem_size:
+        type: scalar-unit.size
+        constraints:
+          - greater_or_equal: 0 MB
+  tosca.datatypes.nfv.riftio.paired_thread_map:
+    properties:
+      thread_a:
+        type: integer
+        required: true
+        constraints:
+          - greater_or_equal: 0
+      thread_b:
+        type: integer
+        required: true
+        constraints:
+          - greater_or_equal: 0
+
+  tosca.datatypes.nfv.riftio.paired_threads:
+    properties:
+      num_paired_threads:
+        type: integer
+        constraints:
+          - greater_or_equal: 1
+      paired_thread_ids:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.riftio.paired_thread_map
+        constraints:
+          - max_length: 16
+        required: false
+
+  tosca.datatypes.compute.riftio.numa:
+    properties:
+      id:
+        type: integer
+        constraints:
+          - greater_or_equal: 0
+      vcpus:
+        type: list
+        entry_schema:
+          type: integer
+          constraints:
+            -  greater_or_equal: 0
+        required: false
+      mem_size:
+        type: scalar-unit.size
+        constraints:
+          - greater_or_equal: 0 MB
+        required: false
+      om_numa_type:
+        type: string
+        description: Openmano Numa type selection
+        constraints:
+          - valid_values: [cores, paired-threads, threads]
+        required: false
+      num_cores:
+        type: integer
+        description: Use when om_numa_type is cores
+        constraints:
+          - greater_or_equal: 1
+        required: false
+      paired_threads:
+        type: tosca.datatypes.nfv.riftio.paired_threads
+        description: Use when om_numa_type is paired-threads
+        required: false
+      num_threads:
+        type: integer
+        description: Use when om_numa_type is threads
+        constraints:
+          - greater_or_equal: 1
+        required: false
+  
+  tosca.nfv.datatypes.pathType:
+    properties:
+      forwarder:
+        type: string
+        required: true
+      capability:
+        type: string
+        required: true
+
+  tosca.nfv.datatypes.aclType:
+    properties:
+      eth_type:
+        type: string
+        required: false
+      eth_src:
+        type: string
+        required: false
+      eth_dst:
+        type: string
+        required: false
+      vlan_id:
+        type: integer
+        constraints:
+          - in_range: [ 1, 4094 ]
+        required: false
+      vlan_pcp:
+        type: integer
+        constraints:
+          - in_range: [ 0, 7 ]
+        required: false
+      mpls_label:
+        type: integer
+        constraints:
+          - in_range: [ 16, 1048575]
+        required: false
+      mpls_tc:
+        type: integer
+        constraints:
+          - in_range: [ 0, 7 ]
+        required: false
+      ip_dscp:
+        type: integer
+        constraints:
+          - in_range: [ 0, 63 ]
+        required: false
+      ip_ecn:
+        type: integer
+        constraints:
+          - in_range: [ 0, 3 ]
+        required: false
+      ip_src_prefix:
+        type: string
+        required: false
+      ip_dst_prefix:
+        type: string
+        required: false
+      ip_proto:
+        type: integer
+        constraints:
+          - in_range: [ 1, 254 ]
+        required: false
+      destination_port_range:
+        type: string
+        required: false
+      source_port_range:
+        type: string
+        required: false
+      network_src_port_id:
+        type: string
+        required: false
+      network_dst_port_id:
+        type: string
+        required: false
+      network_id:
+        type: string
+        required: false
+      network_name:
+        type: string
+        required: false
+      tenant_id:
+        type: string
+        required: false
+      icmpv4_type:
+        type: integer
+        constraints:
+          - in_range: [ 0, 254 ]
+        required: false
+      icmpv4_code:
+        type: integer
+        constraints:
+          - in_range: [ 0, 15 ]
+        required: false
+      arp_op:
+        type: integer
+        constraints:
+          - in_range: [ 1, 25 ]
+        required: false
+      arp_spa:
+        type: string
+        required: false
+      arp_tpa:
+        type: string
+        required: false
+      arp_sha:
+        type: string
+        required: false
+      arp_tha:
+        type: string
+        required: false
+      ipv6_src:
+        type: string
+        required: false
+      ipv6_dst:
+        type: string
+        required: false
+      ipv6_flabel:
+        type: integer
+        constraints:
+          - in_range: [ 0, 1048575]
+        required: false
+      icmpv6_type:
+        type: integer
+        constraints:
+          - in_range: [ 0, 255]
+        required: false
+      icmpv6_code:
+        type: integer
+        constraints:
+          - in_range: [ 0, 7]
+        required: false
+      ipv6_nd_target:
+        type: string
+        required: false
+      ipv6_nd_sll:
+        type: string
+        required: false
+      ipv6_nd_tll:
+        type: string
+        required: false
+
+  
+  tosca.datatypes.nfv.riftio.vnf_configuration:
+    properties:
+      config_type:
+        type: string
+        description: >-
+          Type of the configuration agent to use
+        constraints:
+          - valid_values: [script, netconf, rest, juju]
+      config_details:
+        type: map
+        description: >-
+          Specify the details for the config agent, like
+          script type, juju charm to use, etc.
+      config_template:
+        required: false
+        type: string
+      config_delay:
+        type: integer
+        constraints:
+        - greater_or_equal: 0
+        default: 0
+        required: false
+      config_priority:
+        type: integer
+        constraints:
+        - greater_than: 0
+
+  tosca.datatypes.nfv.riftio.parameter_value:
+    properties:
+      name:
+        type: string
+        description: Name of the parameter
+      value:
+        type: string
+        description: Value of the parameter
+
+  tosca.datatypes.nfv.riftio.config_primitive:
+    properties:
+      name:
+        type: string
+      seq:
+        type: integer
+        description: >-
+          Order in which to apply, when multiple ones are defined
+        default: 0
+        constraints:
+          - greater_or_equal: 0
+      parameter:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.riftio.parameter_value
+      user_defined_script:
+        type: string
+  tosca.datatypes.nfv.riftio.primitive_parameter:
+    properties:
+      data_type:
+        type: string
+        description: >-
+          Data type associated with the name
+        constraints:
+          - valid_values: [string, integer, boolean]
+      mandatory:
+        type: boolean
+        description: >-
+          If this field is mandatory
+        default: false
+        required: false
+      default_value:
+        type: string
+        description: >-
+          The default value for this field
+        required: false
+      parameter_pool:
+        type: string
+        description: >-
+          Parameter pool name to use for this parameter
+        required: false
+      read_only:
+        type: boolean
+        description: >-
+          The value should be greyed out by the UI.
+          Only applies to parameters with default values.
+        required: false
+        default: false
+      hidden:
+        type: boolean
+        description: >-
+          The field should be hidden by the UI.
+          Only applies to parameters with default values.
+        required: false
+        default: false
+  tosca.datatypes.nfv.riftio.primitive_parameter_group:
+    properties:
+      name:
+        type: string
+        description: >-
+          Name of the parameter group
+      mandatory:
+        type: boolean
+        description: >-
+          If this group is mandatory
+        default: false
+        required: false
+      parameter:
+        type: map
+        description: >-
+          List of parameters for the service primitive
+        entry_schema: osca.datatypes.riftio.primitive_parameter
+
+  tosca.datatypes.nfv.riftio.vnf_primitive_group:
+    properties:
+      vnf_name:
+        type: string
+        description: >-
+          Name of the VNF in the NS
+      primitive:
+        type: map
+        entry_schema:
+          type: string
+        description: >-
+          Index and name of the primitive
+
+
+capability_types:
+  tosca.capabilities.nfv.riftio.mgmt_interface:
+    derived_from: tosca.capabilities.Endpoint
+    properties:
+      static_ip:
+        type: string
+        required: false
+        description: >-
+          Specifies the static IP address for managing the VNF
+      connection_point:
+        type: string
+        required: false
+        description: >-
+          Use the ip address associated with this connection point
+      dashboard_params:
+        type: tosca.datatypes.nfv.riftio.dashboard_params
+        required: false
+        description: >-
+          Parameters for the VNF dashboard
+  tosca.capabilities.nfv.riftio.monitoring_param:
+    derived_from: tosca.capabilities.nfv.Metric
+    properties:
+      name:
+        type: string
+        required: false
+      description:
+        type: string
+        required: false
+      protocol:
+        type: string
+        default: http
+        constraints:
+          - equal: http
+      polling_interval:
+        type: scalar-unit.time
+        description: >-
+          The HTTP polling interval in seconds
+        default: 2 s
+      username:
+        type: string
+        description: >-
+          The HTTP basic auth username
+        required: false
+      password:
+        type: string
+        description: >-
+          The HTTP basic auth password
+        required: false
+      method:
+        type: string
+        description: >-
+          This is the method to be performed at the uri.
+          GET by default for action
+        default: get
+        constraints:
+          - valid_values: [post, put, get, delete, options, patch]
+      headers:
+        type: map
+        entry_schema:
+          type: string
+        description: >-
+          Custom HTTP headers to put on HTTP request
+        required: false
+      json_query_method:
+        type: string
+        description: >-
+          The method to extract a value from a JSON response
+            namekey    - Use the name as the key for a non-nested value.
+            jsonpath   - Use jsonpath-rw implemenation to extract a value.
+            objectpath - Use objectpath implemenation to extract a value.
+        constraints:
+          - valid_values: [namekey, jsonpath, objectpath]
+        default: namekey
+      json_query_path:
+        type: string
+        description: >-
+          The json path to use to extract value from JSON structure
+        required: false
+      json_object_path:
+        type: string
+        description: >-
+          The object path to use to extract value from JSON structure
+        required: false
+      ui_data:
+        type: tosca.datatypes.nfv.riftio.monitoring_param_ui
+        required: false
+      constraints:
+        type: tosca.datatypes.nfv.riftio.monitoring_param_value
+        required: false
+  tosca.capabilities.nfv.riftio.numa_extension:
+    derived_from: tosca.capabilities.Root
+    properties:
+      node_cnt:
+        type: integer
+        description: >-
+          The number of numa nodes to expose to the VM
+        constraints:
+          - greater_or_equal: 0
+      mem_policy:
+        type: string
+        description: >-
+          This policy specifies how the memory should
+                   be allocated in a multi-node scenario.
+                   STRICT    - The memory must be allocated
+                               strictly from the memory attached
+                               to the NUMA node.
+                   PREFERRED - The memory should be allocated
+                               preferentially from the memory
+                               attached to the NUMA node
+        constraints:
+          - valid_values: [strict, preferred, STRICT, PREFERRED]
+      node:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.compute.riftio.numa
+  tosca.capabilities.nfv.riftio.vswitch_epa:
+    derived_from: tosca.capabilities.Root
+    properties:
+      ovs_acceleration:
+        type: string
+        description: |-
+          Specifies Open vSwitch acceleration mode.
+             MANDATORY - OVS acceleration is required
+             PREFERRED - OVS acceleration is preferred
+        constraints:
+          - valid_values: [mandatory, preferred, disabled, MANDATORY, PREFERRED, DISABLED]
+      ovs_offload:
+        type: string
+        description: |-
+          Specifies Open vSwitch hardware offload mode.
+             MANDATORY - OVS offload is required
+             PREFERRED - OVS offload is preferred
+        constraints:
+          - valid_values: [mandatory, preferred, disabled, MANDATORY, PREFERRED, DISABLED]
+
+  tosca.capabilities.nfv.riftio.hypervisor_epa:
+    derived_from: tosca.capabilities.Root
+    properties:
+      type:
+        type: string
+        description: |-
+          Specifies the type of hypervisor.
+        constraints:
+          - valid_values: [prefer_kvm, require_kvm, PREFER_KVM, REQUIRE_KVM]
+      version:
+        type: string
+
+  tosca.capabilities.nfv.riftio.host_epa:
+    derived_from: tosca.capabilities.Root
+    properties:
+      cpu_model:
+        type: string
+        description: >-
+          Host CPU model. Examples include SandyBridge,
+          IvyBridge, etc.
+        required: false
+        constraints:
+          - valid_values:
+              - prefer_westmere
+              - require_westmere
+              - prefer_sandbridge
+              - require_sandybridge
+              - prefer_ivybridge
+              - require_ivybridge
+              - prefer_haswell
+              - require_haswell
+              - prefer_broadwell
+              - require_broadwell
+              - prefer_nehalem
+              - require_nehalem
+              - prefer_penryn
+              - require_penryn
+              - prefer_conroe
+              - require_conroe
+              - prefer_core2duo
+              - require_core2duo
+              - PREFER_WESTMERE
+              - REQUIRE_WESTMERE
+              - PREFER_SANDBRIDGE
+              - REQUIRE_SANDYBRIDGE
+              - PREFER_IVYBRIDGE
+              - REQUIRE_IVYBRIDGE
+              - PREFER_HASWELL
+              - REQUIRE_HASWELL
+              - PREFER_BROADWELL
+              - REQUIRE_BROADWELL
+              - PREFER_NEHALEM
+              - REQUIRE_NEHALEM
+              - PREFER_PENRYN
+              - REQUIRE_PENRYN
+              - PREFER_CONROE
+              - REQUIRE_CONROE
+              - PREFER_CORE2DUO
+              - REQUIRE_CORE2DUO
+      cpu_arch:
+        type: string
+        description: >-
+          Host CPU architecture
+        required: false
+        constraints:
+          - valid_values:
+              - prefer_x86
+              - require_x86
+              - prefer_x86_64
+              - require_x86_64
+              - prefer_i686
+              - require_i686
+              - prefer_ia64
+              - require_ia64
+              - prefer_armv7
+              - require_armv7
+              - prefer_armv8
+              - require_armv8
+              - PREFER_X86
+              - REQUIRE_X86
+              - PREFER_X86_64
+              - REQUIRE_X86_64
+              - PREFER_I686
+              - REQUIRE_I686
+              - PREFER_IA64
+              - REQUIRE_IA64
+              - PREFER_ARMV7
+              - REQUIRE_ARMV7
+              - PREFER_ARMV8
+              - REQUIRE_ARMV8
+      cpu_vendor:
+        type: string
+        description: >-
+          Host CPU vendor
+        required: false
+        constraints:
+          - valid_values:
+              - prefer_intel
+              - require_intel
+              - prefer_amd
+              - requie_amd
+              - PREFER_INTEL
+              - REQUIRE_INTEL
+              - PREFER_AMD
+              - REQUIE_AMD
+      cpu_socket_count:
+        type: integer
+        description: >-
+          Number of sockets on the host
+        required: false
+        constraints:
+          - greater_than : 0
+      cpu_core_count:
+        type: integer
+        description: >-
+          Number of cores on the host
+        required: false
+        constraints:
+          - greater_than : 0
+      cpu_core_thread_count:
+        type: integer
+        description: >-
+          Number of threads per core on the host
+        required: false
+        constraints:
+          - greater_than : 0
+      cpu_feature:
+        type: list
+        entry_schema:
+          type: string
+        description: |-
+          Enumeration for CPU features.
+
+          AES- CPU supports advanced instruction set for
+          AES (Advanced Encryption Standard).
+
+          CAT- Cache Allocation Technology (CAT) allows
+          an Operating System, Hypervisor, or similar
+          system management agent to specify the amount
+          of L3 cache (currently the last-level cache
+          in most server and client platforms) space an
+          application can fill (as a hint to hardware
+          functionality, certain features such as power
+          management may override CAT settings).
+
+          CMT- Cache Monitoring Technology (CMT) allows
+          an Operating System, Hypervisor, or similar
+          system management agent to determine the
+          usage of cache based on applications running
+          on the platform. The implementation is
+          directed at L3 cache monitoring (currently
+          the last-level cache in most server and
+          client platforms).
+
+          DDIO- Intel Data Direct I/O (DDIO) enables
+          Ethernet server NICs and controllers talk
+          directly to the processor cache without a
+          detour via system memory. This enumeration
+          specifies if the VM requires a DDIO
+          capable host.
+        required: false
+        constraints:
+          -valid_values:
+            - prefer_aes
+            - require_aes
+            - prefer_cat
+            - require_cat
+            - prefer_cmt
+            - require_cmt
+            - prefer_ddio
+            - require_ddio
+            - prefer_vme
+            - require_vme
+            - prefer_de
+            - require_de
+            - prefer_pse
+            - require_pse
+            - prefer_tsc
+            - require_tsc
+            - prefer_msr
+            - require_msr
+            - prefer_pae
+            - require_pae
+            - prefer_mce
+            - require_mce
+            - prefer_cx8
+            - require_cx8
+            - prefer_apic
+            - require_apic
+            - prefer_sep
+            - require_sep
+            - prefer_mtrr
+            - require_mtrr
+            - prefer_pge
+            - require_pge
+            - prefer_mca
+            - require_mca
+            - prefer_cmov
+            - require_cmov
+            - prefer_pat
+            - require_pat
+            - prefer_pse36
+            - require_pse36
+            - prefer_clflush
+            - require_clflush
+            - prefer_dts
+            - require_dts
+            - prefer_acpi
+            - require_acpi
+            - prefer_mmx
+            - require_mmx
+            - prefer_fxsr
+            - require_fxsr
+            - prefer_sse
+            - require_sse
+            - prefer_sse2
+            - require_sse2
+            - prefer_ss
+            - require_ss
+            - prefer_ht
+            - require_ht
+            - prefer_tm
+            - require_tm
+            - prefer_ia64
+            - require_ia64
+            - prefer_pbe
+            - require_pbe
+            - prefer_rdtscp
+            - require_rdtscp
+            - prefer_pni
+            - require_pni
+            - prefer_pclmulqdq
+            - require_pclmulqdq
+            - prefer_dtes64
+            - require_dtes64
+            - prefer_monitor
+            - require_monitor
+            - prefer_ds_cpl
+            - require_ds_cpl
+            - prefer_vmx
+            - require_vmx
+            - prefer_smx
+            - require_smx
+            - prefer_est
+            - require_est
+            - prefer_tm2
+            - require_tm2
+            - prefer_ssse3
+            - require_ssse3
+            - prefer_cid
+            - require_cid
+            - prefer_fma
+            - require_fma
+            - prefer_cx16
+            - require_cx16
+            - prefer_xtpr
+            - require_xtpr
+            - prefer_pdcm
+            - require_pdcm
+            - prefer_pcid
+            - require_pcid
+            - prefer_dca
+            - require_dca
+            - prefer_sse4_1
+            - require_sse4_1
+            - prefer_sse4_2
+            - require_sse4_2
+            - prefer_x2apic
+            - require_x2apic
+            - prefer_movbe
+            - require_movbe
+            - prefer_popcnt
+            - require_popcnt
+            - prefer_tsc_deadline_timer
+            - require_tsc_deadline_timer
+            - prefer_xsave
+            - require_xsave
+            - prefer_avx
+            - require_avx
+            - prefer_f16c
+            - require_f16c
+            - prefer_rdrand
+            - require_rdrand
+            - prefer_fsgsbase
+            - require_fsgsbase
+            - prefer_bmi1
+            - require_bmi1
+            - prefer_hle
+            - require_hle
+            - prefer_avx2
+            - require_avx2
+            - prefer_smep
+            - require_smep
+            - prefer_bmi2
+            - require_bmi2
+            - prefer_erms
+            - require_erms
+            - prefer_invpcid
+            - require_invpcid
+            - prefer_rtm
+            - require_rtm
+            - prefer_mpx
+            - require_mpx
+            - prefer_rdseed
+            - require_rdseed
+            - prefer_adx
+            - require_adx
+            - prefer_smap
+            - require_smap
+            - PREFER_AES
+            - REQUIRE_AES
+            - PREFER_CAT
+            - REQUIRE_CAT
+            - PREFER_CMT
+            - REQUIRE_CMT
+            - PREFER_DDIO
+            - REQUIRE_DDIO
+            - PREFER_VME
+            - REQUIRE_VME
+            - PREFER_DE
+            - REQUIRE_DE
+            - PREFER_PSE
+            - REQUIRE_PSE
+            - PREFER_TSC
+            - REQUIRE_TSC
+            - PREFER_MSR
+            - REQUIRE_MSR
+            - PREFER_PAE
+            - REQUIRE_PAE
+            - PREFER_MCE
+            - REQUIRE_MCE
+            - PREFER_CX8
+            - REQUIRE_CX8
+            - PREFER_APIC
+            - REQUIRE_APIC
+            - PREFER_SEP
+            - REQUIRE_SEP
+            - PREFER_MTRR
+            - REQUIRE_MTRR
+            - PREFER_PGE
+            - REQUIRE_PGE
+            - PREFER_MCA
+            - REQUIRE_MCA
+            - PREFER_CMOV
+            - REQUIRE_CMOV
+            - PREFER_PAT
+            - REQUIRE_PAT
+            - PREFER_PSE36
+            - REQUIRE_PSE36
+            - PREFER_CLFLUSH
+            - REQUIRE_CLFLUSH
+            - PREFER_DTS
+            - REQUIRE_DTS
+            - PREFER_ACPI
+            - REQUIRE_ACPI
+            - PREFER_MMX
+            - REQUIRE_MMX
+            - PREFER_FXSR
+            - REQUIRE_FXSR
+            - PREFER_SSE
+            - REQUIRE_SSE
+            - PREFER_SSE2
+            - REQUIRE_SSE2
+            - PREFER_SS
+            - REQUIRE_SS
+            - PREFER_HT
+            - REQUIRE_HT
+            - PREFER_TM
+            - REQUIRE_TM
+            - PREFER_IA64
+            - REQUIRE_IA64
+            - PREFER_PBE
+            - REQUIRE_PBE
+            - PREFER_RDTSCP
+            - REQUIRE_RDTSCP
+            - PREFER_PNI
+            - REQUIRE_PNI
+            - PREFER_PCLMULQDQ
+            - REQUIRE_PCLMULQDQ
+            - PREFER_DTES64
+            - REQUIRE_DTES64
+            - PREFER_MONITOR
+            - REQUIRE_MONITOR
+            - PREFER_DS_CPL
+            - REQUIRE_DS_CPL
+            - PREFER_VMX
+            - REQUIRE_VMX
+            - PREFER_SMX
+            - REQUIRE_SMX
+            - PREFER_EST
+            - REQUIRE_EST
+            - PREFER_TM2
+            - REQUIRE_TM2
+            - PREFER_SSSE3
+            - REQUIRE_SSSE3
+            - PREFER_CID
+            - REQUIRE_CID
+            - PREFER_FMA
+            - REQUIRE_FMA
+            - PREFER_CX16
+            - REQUIRE_CX16
+            - PREFER_XTPR
+            - REQUIRE_XTPR
+            - PREFER_PDCM
+            - REQUIRE_PDCM
+            - PREFER_PCID
+            - REQUIRE_PCID
+            - PREFER_DCA
+            - REQUIRE_DCA
+            - PREFER_SSE4_1
+            - REQUIRE_SSE4_1
+            - PREFER_SSE4_2
+            - REQUIRE_SSE4_2
+            - PREFER_X2APIC
+            - REQUIRE_X2APIC
+            - PREFER_MOVBE
+            - REQUIRE_MOVBE
+            - PREFER_POPCNT
+            - REQUIRE_POPCNT
+            - PREFER_TSC_DEADLINE_TIMER
+            - REQUIRE_TSC_DEADLINE_TIMER
+            - PREFER_XSAVE
+            - REQUIRE_XSAVE
+            - PREFER_AVX
+            - REQUIRE_AVX
+            - PREFER_F16C
+            - REQUIRE_F16C
+            - PREFER_RDRAND
+            - REQUIRE_RDRAND
+            - PREFER_FSGSBASE
+            - REQUIRE_FSGSBASE
+            - PREFER_BMI1
+            - REQUIRE_BMI1
+            - PREFER_HLE
+            - REQUIRE_HLE
+            - PREFER_AVX2
+            - REQUIRE_AVX2
+            - PREFER_SMEP
+            - REQUIRE_SMEP
+            - PREFER_BMI2
+            - REQUIRE_BMI2
+            - PREFER_ERMS
+            - REQUIRE_ERMS
+            - PREFER_INVPCID
+            - REQUIRE_INVPCID
+            - PREFER_RTM
+            - REQUIRE_RTM
+            - PREFER_MPX
+            - REQUIRE_MPX
+            - PREFER_RDSEED
+            - REQUIRE_RDSEED
+            - PREFER_ADX
+            - REQUIRE_ADX
+            - PREFER_SMAP
+            - REQUIRE_SMAP
+      om_cpu_model_string:
+        type: string
+        description: >-
+          Openmano CPU model string
+        required: false
+      om_cpu_feature:
+        type: list
+        entry_schema:
+          type: string
+        description: >-
+          List of openmano CPU features
+        required: false
+
+  tosca.capabilities.nfv.riftio.sfc:
+    derived_from: tosca.capabilities.Root
+    description: >-
+      Service Function Chaining support on this VDU
+    properties:
+      sfc_type:
+        type: string
+        description: >-
+          Type of node in Service Function Chaining Architecture
+        constraints:
+          - valid_values: [unaware, classifier, sf, sff, UNAWARE, CLASSIFIER, SF, SFF]
+        default: unaware
+      sf_type:
+        type: string
+        description: >-
+          Type of Service Function.
+             NOTE- This needs to map with Service Function Type in ODL to
+             support VNFFG. Service Function Type is manadatory param in ODL
+             SFC.
+        required: false
+  tosca.capabilities.Compute.Container.Architecture:
+    derived_from: tosca.capabilities.Container
+    properties:
+      mem_page_size:
+        type: string
+        description: >-
+          Memory page allocation size. If a VM requires
+          hugepages, it should choose huge or size_2MB
+          or size_1GB. If the VM prefers hugepages, it
+          should chose prefer_huge.
+             huge/large         - Require hugepages (either 2MB or 1GB)
+             normal       - Does not require hugepages
+             size_2MB     - Requires 2MB hugepages
+             size_1GB     - Requires 1GB hugepages
+             prefer_huge  - Application perfers hugepages
+          NOTE - huge and normal is only defined in standards as of
+                 now.
+        required: false
+        constraints:
+          - valid_values: [normal, large, huge, size_2MB, size_1GB, prefer_huge, NORMAL,LARGE, HUGE, SIZE_2MB, SIZE_1GB, PREFER_HUGE]
+      cpu_allocation:
+        type: tosca.datatypes.compute.Container.Architecture.CPUAllocation
+        required: false
+      numa_nodes:
+        type: map
+        required: false
+        entry_schema:
+          type: tosca.datatypes.compute.Container.Architecture.NUMA
+
+
+node_types:
+  tosca.nodes.nfv.riftio.VDU1:
+    derived_from: tosca.nodes.nfv.VDU
+    properties:
+      description:
+        type: string
+        required: false
+      image:
+        description: >-
+          If an image is specified here, it is assumed that the image
+          is already present in the RO or VIM and not in the package.
+        type: string
+        required: false
+      image_checksum:
+        type: string
+        description: >-
+          Image checksum for the image in RO or VIM.
+        required: false
+      cloud_init:
+        description: >-
+          Inline cloud-init specification
+        required: false
+        type: string
+      count:
+        default: 1
+        type: integer
+    capabilities:
+      virtualLink:
+        type: tosca.capabilities.nfv.VirtualLinkable
+      monitoring_param_1:
+        type: tosca.capabilities.nfv.riftio.monitoring_param
+      mgmt_interface:
+        type: tosca.capabilities.nfv.riftio.mgmt_interface
+      monitoring_param:
+        type: tosca.capabilities.nfv.riftio.monitoring_param
+      numa_extension:
+        type: tosca.capabilities.nfv.riftio.numa_extension
+      vswitch_epa:
+        type: tosca.capabilities.nfv.riftio.vswitch_epa
+      hypervisor_epa:
+        type: tosca.capabilities.nfv.riftio.hypervisor_epa
+      host_epa:
+        type: tosca.capabilities.nfv.riftio.host_epa
+  tosca.nodes.nfv.riftio.CP1:
+    derived_from: tosca.nodes.nfv.CP
+    properties:
+      cp_type:
+        description: Type of the connection point
+        type: string
+        default: VPORT
+        constraints:
+          - valid_values: [VPORT]
+      name:
+        description: Name of the connection point
+        type: string
+        required: false
+      vdu_intf_name:
+        description: Name of the interface on VDU
+        type: string
+      vdu_intf_type:
+        description: >-
+          Specifies the type of virtual interface
+             between VM and host.
+             VIRTIO          - Use the traditional VIRTIO interface.
+             PCI-PASSTHROUGH - Use PCI-PASSTHROUGH interface.
+             SR-IOV          - Use SR-IOV interface.
+             E1000           - Emulate E1000 interface.
+             RTL8139         - Emulate RTL8139 interface.
+             PCNET           - Emulate PCNET interface.
+             OM-MGMT         - Used to specify openmano mgmt external-connection type
+        type: string
+        constraints:
+          - valid_values: [OM-MGMT, VIRTIO, E1000, SR-IOV]
+      bandwidth:
+        type: integer
+        description: Aggregate bandwidth of the NIC
+        constraints:
+          - greater_or_equal: 0
+        required: false
+      vpci:
+        type: string
+        description: >-
+          Specifies the virtual PCI address. Expressed in
+          the following format dddd:dd:dd.d. For example
+          0000:00:12.0. This information can be used to
+          pass as metadata during the VM creation.
+        required: false
+    capabilities:
+      sfc:
+        type: tosca.capabilities.nfv.riftio.sfc
+  tosca.nodes.nfv.riftio.VNF1:
+    derived_from: tosca.nodes.nfv.VNF
+    properties:
+      member_index:
+        type: integer
+        constraints:
+          - greater_or_equal: 1
+        description: Index of the VNF in the NS
+        required: false
+      start_by_default:
+        type: boolean
+        default: true
+        description: Start this VNF on NS instantiate
+      logo:
+        type: string
+        description: >-
+          Logo to display with the VNF in the orchestrator
+        required: false
+    capabilities:      
+      mgmt_interface:
+        type: tosca.capabilities.nfv.riftio.mgmt_interface
+      monitoring_param:
+        type: tosca.capabilities.nfv.riftio.monitoring_param
+      sfc:
+        type: tosca.capabilities.nfv.riftio.sfc
+  tosca.nodes.nfv.riftio.ELAN:
+    derived_from: tosca.nodes.nfv.VL.ELAN
+    properties:
+      description:
+        type: string
+        required: false
+      network_name:
+        type: string
+        description: >-
+          Name of network in VIM account. This is used to indicate
+          pre-provisioned network name in cloud account.
+        required: false
+      root_bandwidth:
+        type: integer
+        description: >-
+          This is the aggregate bandwidth
+        constraints:
+          - greater_or_equal: 0
+        required: false
+      leaf_bandwidth:
+        type: integer
+        description: >-
+          This is the bandwidth of branches
+        constraints:
+          - greater_or_equal: 0
+        required: false
+  tosca.nodes.nfv.riftio.FP1:
+    derived_from: tosca.nodes.nfv.FP
+    properties:
+      id:
+        type: integer
+        required: false
+      policy:
+        type: tosca.nfv.datatypes.policyType
+        required: true
+        description: policy to use to match traffic for this FP
+      path:
+        type: list
+        required: true
+        entry_schema:
+          type: tosca.nfv.datatypes.pathType
+      cp:
+        type: tosca.nfv.datatypes.pathType
+        required: true
+
+
+
+artifact_types:
+  tosca.artifacts.Deployment.riftio.cloud_init_file:
+    derived_from: tosca.artifacts.Deployment
+    file:
+      type: string
+
+  tosca.artifacts.Deployment.Image.riftio.QCOW2:
+    derived_from: tosca.artifacts.Deployment.Image.VM.QCOW2
+    image_checksum:
+      required: false
+      type: string
+
+group_types:
+  tosca.groups.nfv.VNFFG:
+    derived_from: tosca.groups.Root
+    properties:
+      vendor:
+        type: string
+        required: true
+        description: name of the vendor who generate this VNFFG
+      version:
+        type: string
+        required: true
+        description: version of this VNFFG
+      number_of_endpoints:
+        type: integer
+        required: true
+        description: count of the external endpoints included in this VNFFG
+      dependent_virtual_link:
+        type: list
+        entry_schema:
+          type: string
+        required: true
+        description: Reference to a VLD used in this Forwarding Graph
+      connection_point:
+        type: list
+        entry_schema:
+          type: string
+        required: true
+        description: Reference to Connection Points forming the VNFFG
+      constituent_vnfs:
+        type: list
+        entry_schema:
+          type: string
+        required: true
+        description: Reference to a list of VNFD used in this VNF Forwarding Graph
+    members: [ tosca.nodes.nfv.FP ]
+
+  tosca.groups.nfv.riftio.scaling:
+    derived_from: tosca.groups.Root
+    properties:
+      name:
+        type: string
+      min_instances:
+        type: integer
+        description: >-
+          Minimum instances of the scaling group which are allowed.
+          These instances are created by default when the network service
+          is instantiated.
+      max_instances:
+        type: integer
+        description: >-
+          Maximum instances of this scaling group that are allowed
+          in a single network service. The network service scaling
+          will fail, when the number of service group instances
+          exceed the max-instance-count specified.
+      cooldown_time:
+        type: integer
+        description: >-
+          The duration after a scaling-in/scaling-out action has been
+          triggered, for which there will be no further optional
+      ratio:
+        type: map
+        entry_schema:
+          type: integer
+        description: >-
+          Specify the number of instances of each VNF to instantiate
+          for a scaling action
+    members: [tosca.nodes.nfv.VNF]
+    interfaces:
+      action:
+        type: tosca.interfaces.nfv.riftio.scaling.action
+
+interface_types:
+  tosca.interfaces.nfv.riftio.scaling.action:
+    pre_scale_in:
+      description: Operation to execute before a scale in
+    post_scale_in:
+      description: Operation to execute after a scale in
+    pre_scale_out:
+      description: Operation to execute before a scale out
+    post_scale_out:
+      description: Operation to execute after a scale out
+
+policy_types:
+  tosca.policies.nfv.riftio.placement:
+    derived_from: tosca.policies.Placement
+    properties:
+      name:
+        type: string
+        description: >-
+          Place group construct to define the compute resource placement strategy
+          in cloud environment
+      requirement:
+        type: string
+        description: >-
+          This is free text space used to describe the intent/rationale
+          behind this placement group. This is for human consumption only
+      strategy:
+        type: string
+        description: >-
+          Strategy associated with this placement group
+             Following values are possible
+               COLOCATION - Colocation strategy imply intent to share the physical
+                            infrastructure (hypervisor/network) among all members
+                            of this group.
+               ISOLATION - Isolation strategy imply intent to not share the physical
+                           infrastructure (hypervisor/network) among the members
+                           of this group.
+        constraints:
+          valid_values:
+            - COLOCATION
+            - ISOLATION
+  tosca.policies.nfv.riftio.vnf_configuration:
+    derived_from: tosca.policies.Root
+    properties:
+      config:
+        type: tosca.datatypes.nfv.riftio.vnf_configuration
+      initial_config:
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.riftio.config_primitive
+  tosca.policies.nfv.riftio.vnf_service_primitives:
+    derived_from: tosca.policies.Root
+    properties:
+      parameter:
+        type: map
+        entry_schema:
+          type: primitive_parameter
+  tosca.policies.nfv.riftio.ns_service_primitives:
+    derived_from: tosca.policies.Root
+    properties:
+      parameter:
+        type: map
+        entry_schema:
+          type: primitive_parameter
+      parameter_group:
+        type: tosca.datatypes.nfv.riftio.primitive_parameter_group
+        description: >-
+          Grouping of parameters which are logically grouped in UI
+        required: false
+      vnf_primitive_group:
+        type: tosca.datatypes.nfv.riftio.vnf_primitive_group
+        description: >-
+          List of service primitives grouped by VNF
+        required: false
+      user_defined_script:
+        type: string
+        description: >-
+          A user defined script
+        required: false
+  tosca.policies.nfv.riftio.initial_config_primitive:
+    derived_from: tosca.policies.Root
+    properties:
+      name:
+        type: string
+      seq:
+        type: integer
+        description: >-
+          Order in which to apply, when multiple ones are defined
+        default: 0
+        constraints:
+          - greater_or_equal: 0
+      parameter:
+        type: map
+        entry_schema:
+          type: string
+      user_defined_script:
+        type: string
+  tosca.policies.nfv.riftio.users:
+    derived_from: tosca.policies.Root
+    description: >-
+      Specify list of public keys to be injected as
+      part of NS instantitation. Use default as entry,
+      to specify the key pairs for default user.
+    properties:
+      user_info:
+        type: string
+        description: >-
+          The user\'s real name
+        required: false
+      key_pairs:
+        type: map
+        description: >-
+          List of public keys for the user
+        entry_schema:
+          type: string
+        required: true
+  tosca.policies.nfv.riftio.dependency:
+    derived_from: tosca.policies.Root
+    description: >-
+      Map dependency between VDUs or VNFs
+    properties:
+      parameter:
+        type: map
+        entry_schema:
+          type: string
+        description: >-
+          Parameter and value for the config
+  tosca.nfv.datatypes.policyType:
+    properties:
+      type:
+        type: string
+        required: false
+        constraints:
+          - valid_values: [ ACL ]
+      criteria:
+        type: list
+        required: true
+        entry_schema:
+          type: tosca.nfv.datatypes.aclType
+
+  
+
index f05933b..7143e67 100644 (file)
@@ -17,7 +17,7 @@ from rift.mano.yang_translator.common.utils import _
 
 
 class ToscaResource(object):
-    '''Base class for YANG node type translation to RIFT.io TOSCA type.'''
+    '''Base class for YANG node type translation to RIFT.io SUBSTITUTION_MAPPINGtype.'''
 
     # Used when creating the resource, so keeping separate
     # from REQUIRED_FIELDS below
@@ -26,8 +26,10 @@ class ToscaResource(object):
     REQUIRED_FIELDS = (DESC, VERSION, VENDOR, ID) = \
                       ('description', 'version', 'vendor', 'id')
 
-    COMMON_FIELDS = (PATH, PORT, HOST, XPATH, TYPE, COUNT, FILE) = \
-                    ('path', 'port', 'host', 'xpath', 'type', 'count', 'file')
+    COMMON_FIELDS = (PATH, PORT, HOST, XPATH, TYPE, COUNT, FILE, 
+                    NFV_COMPUTE, HOST_EPA, VSWITCH_EPA, HYPERVISOR_EPA, GUEST_EPA) = \
+                    ('path', 'port', 'host', 'xpath', 'type', 'count', 'file', 'nfv_compute', 
+                     'host_epa', 'vswitch_epa', 'hypervisor_epa', 'guest_epa')
 
     IGNORE_FIELDS = ['short_name']
 
@@ -66,17 +68,17 @@ class ToscaResource(object):
                  GROUP_TYPES, POLICY_TYPES, REQUIREMENTS,
                  ARTIFACTS, PROPERTIES, INTERFACES,
                  CAPABILITIES, RELATIONSHIP,
-                 ARTIFACT_TYPES) = \
+                 ARTIFACT_TYPES, TARGETS) = \
                 ('data_types', 'capability_types', 'node_types',
                  'group_types', 'policy_types', 'requirements',
                  'artifacts', 'properties', 'interfaces',
                  'capabilities', 'relationship',
-                 'artifact_types')
+                 'artifact_types', 'targets')
 
     TOSCA_TMPL = (INPUTS, NODE_TMPL, GROUPS, POLICIES,
-                  METADATA, TOPOLOGY_TMPL, OUTPUTS) = \
+                  METADATA, TOPOLOGY_TMPL, OUTPUTS, SUBSTITUTION_MAPPING, IMPORT) = \
                  ('inputs', 'node_templates', 'groups', 'policies',
-                  'metadata', 'topology_template', 'outputs')
+                  'metadata', 'topology_template', 'outputs', 'substitution_mappings', 'imports')
 
     TOSCA_DERIVED = (
         T_VNF_CONFIG,
@@ -91,26 +93,32 @@ class ToscaResource(object):
         T_SCALE_GRP,
         T_ARTF_QCOW2,
         T_INITIAL_CFG,
+        T_ARTF_CLOUD_INIT,
+        T_PLACEMENT,
+        T_ELAN
     ) = \
-        ('tosca.datatypes.network.riftio.vnf_configuration',
+        ('tosca.policies.nfv.riftio.vnf_configuration',
          'tosca.capabilities.riftio.http_endpoint_type',
          'tosca.capabilities.riftio.mgmt_interface_type',
          'tosca.capabilities.riftio.monitoring_param',
-         'tosca.nodes.riftio.VNF1',
-         'tosca.nodes.riftio.VDU1',
-         'tosca.nodes.riftio.CP1',
+         'tosca.nodes.nfv.riftio.VNF1',
+         'tosca.nodes.nfv.riftio.VDU1',
+         'tosca.nodes.nfv.riftio.CP1',
          'tosca.nodes.riftio.VL1',
          'tosca.groups.riftio.ConfigPrimitives',
          'tosca.policies.riftio.ScalingGroup',
          'tosca.artifacts.Deployment.Image.riftio.QCOW2',
-         'tosca.policies.riftio.InitialConfigPrimitive'
+         'tosca.policies.nfv.riftio.initial_config_primitive',
+         'tosca.artifacts.Deployment.riftio.cloud_init_file',
+         'tosca.policies.nfv.riftio.placement',
+         'tosca.nodes.nfv.riftio.ELAN'
         )
 
     SUPPORT_FILES = ( SRC, DEST, EXISTING) = \
                     ('source', 'destination', 'existing')
 
-    SUPPORT_DIRS = (IMAGE_DIR, SCRIPT_DIR,) = \
-                   ('images', 'scripts',)
+    SUPPORT_DIRS = (IMAGE_DIR, SCRIPT_DIR, CLOUD_INIT_DIR) = \
+                   ('images', 'scripts','cloud_init')
 
     def __init__(self,
                  log,
index 7c31df5..95f2cb2 100644 (file)
@@ -36,6 +36,15 @@ class ToscaTemplate(object):
         self.log.debug(_('Converting translated output to tosca template.'))
 
         templates = {}
+        vnfd_templates = {}
+
+        for resource in self.resources:
+            if resource.type == 'vnfd':
+                tmpl = resource.generate_tosca()
+                tmpl = resource.generate_tosca_template(tmpl)
+                self.log.debug(_("TOSCA template generated for {0}:\n{1}").
+                               format(resource.name, tmpl))
+                vnfd_templates[resource.name] = tmpl
 
         for resource in self.resources:
             # Each NSD should generate separate templates
@@ -49,6 +58,14 @@ class ToscaTemplate(object):
                 if len(files):
                     templates[resource.name][self.FILES] = files
 
+        for resource in self.resources:
+            if resource.type == 'vnfd':
+                tmpl = vnfd_templates[resource.name]
+                templates[resource.name] = {self.TOSCA: self.output_to_yaml(tmpl)}
+                files = resource.get_supporting_files()
+                if len(files):
+                    templates[resource.name][self.FILES] = files
+
         return templates
 
     def represent_ordereddict(self, dumper, data):
@@ -66,6 +83,7 @@ class ToscaTemplate(object):
                  ToscaResource.REQUIREMENTS,ToscaResource.ARTIFACTS,
                  ToscaResource.INTERFACES]
         new_node = OrderedDict()
+        self.log.debug("Node to oder: {}".format(node))
         for ent in order:
             if ent in node:
                 new_node.update({ent: node.pop(ent)})
@@ -87,10 +105,18 @@ class ToscaTemplate(object):
         else:
             return nodes
 
+    def ordered_nodes_sub_mapping(self, nodes):
+        new_nodes = OrderedDict()
+        if isinstance(nodes, dict):
+            for name, node in nodes.items():
+                new_nodes.update({name: node})
+            return new_nodes
+        else:
+            return nodes
+
     def output_to_yaml(self, tosca):
         self.log.debug(_('Converting translated output to yaml format.'))
         dict_output = OrderedDict()
-
         dict_output.update({'tosca_definitions_version':
                             tosca['tosca_definitions_version']})
         # Description
@@ -106,6 +132,9 @@ class ToscaTemplate(object):
         if ToscaResource.METADATA in tosca:
             dict_output.update({ToscaResource.METADATA:
                                tosca[ToscaResource.METADATA]})
+        if ToscaResource.IMPORT in tosca:
+            dict_output.update({ToscaResource.IMPORT:
+                               tosca[ToscaResource.IMPORT]})
 
         # Add all types
         types_list = [ToscaResource.DATA_TYPES, ToscaResource.CAPABILITY_TYPES,
@@ -122,9 +151,14 @@ class ToscaTemplate(object):
         if ToscaResource.TOPOLOGY_TMPL in tosca:
             tmpl = OrderedDict()
             for typ in tosca[ToscaResource.TOPOLOGY_TMPL]:
-                tmpl.update({typ:
-                             self.ordered_nodes(
-                                 tosca[ToscaResource.TOPOLOGY_TMPL][typ])})
+                if typ != ToscaResource.SUBSTITUTION_MAPPING:
+                    tmpl.update({typ:
+                                 self.ordered_nodes(
+                                     tosca[ToscaResource.TOPOLOGY_TMPL][typ])})
+                else:
+                    tmpl.update({typ:
+                                 self.ordered_nodes_sub_mapping(
+                                     tosca[ToscaResource.TOPOLOGY_TMPL][typ])})
             dict_output.update({ToscaResource.TOPOLOGY_TMPL: tmpl})
 
         yaml.add_representer(OrderedDict, self.represent_ordereddict)
index f0a6866..707ab7f 100644 (file)
@@ -104,10 +104,11 @@ class TranslateDescriptors(object):
 
         return types_map
 
-    def __init__(self, log, yangs, tosca_template):
+    def __init__(self, log, yangs, tosca_template, vnfd_files=None):
         self.log = log
         self.yangs = yangs
         self.tosca_template = tosca_template
+        self.vnfd_files = vnfd_files
         # list of all TOSCA resources generated
         self.tosca_resources = []
         self.metadata = {}
@@ -143,27 +144,30 @@ class TranslateDescriptors(object):
 
     def _translate_yang(self):
         self.log.debug(_('Translating the descriptors.'))
-        for nsd in self.yangs[self.NSD]:
-            self.log.debug(_("Translate descriptor of type nsd: {}").
-                           format(nsd))
-            tosca_node = TranslateDescriptors. \
-                         YANG_TO_TOSCA_TYPE[self.NSD](
-                             self.log,
-                             nsd.pop(ToscaResource.NAME),
-                             self.NSD,
-                             nsd)
-            self.tosca_resources.append(tosca_node)
-
-        for vnfd in self.yangs[self.VNFD]:
-            self.log.debug(_("Translate descriptor of type vnfd: {}").
-                           format(vnfd))
-            tosca_node = TranslateDescriptors. \
-                         YANG_TO_TOSCA_TYPE[self.VNFD](
-                             self.log,
-                             vnfd.pop(ToscaResource.NAME),
-                             self.VNFD,
-                             vnfd)
-            self.tosca_resources.append(tosca_node)
+        if self.NSD in self.yangs:
+            for nsd in self.yangs[self.NSD]:
+                self.log.debug(_("Translate descriptor of type nsd: {}").
+                               format(nsd))
+                tosca_node = TranslateDescriptors. \
+                             YANG_TO_TOSCA_TYPE[self.NSD](
+                                 self.log,
+                                 nsd.pop(ToscaResource.NAME),
+                                 self.NSD,
+                                 nsd,
+                                 self.vnfd_files)
+                self.tosca_resources.append(tosca_node)
+
+        if self.VNFD in self.yangs:
+            for vnfd in self.yangs[self.VNFD]:
+                self.log.debug(_("Translate descriptor of type vnfd: {}").
+                               format(vnfd))
+                tosca_node = TranslateDescriptors. \
+                             YANG_TO_TOSCA_TYPE[self.VNFD](
+                                 self.log,
+                                 vnfd.pop(ToscaResource.NAME),
+                                 self.VNFD,
+                                 vnfd)
+                self.tosca_resources.append(tosca_node)
 
         # First translate VNFDs
         for node in self.tosca_resources:
index 491bd86..4e421d1 100644 (file)
@@ -49,7 +49,8 @@ class YangNsd(ToscaResource):
                  log,
                  name,
                  type_,
-                 yang):
+                 yang,
+                 vnfd_files):
         super(YangNsd, self).__init__(log,
                                       name,
                                       type_,
@@ -57,10 +58,16 @@ class YangNsd(ToscaResource):
         self.props = {}
         self.inputs = []
         self.vnfds = {}
-        self.vlds = []
+        self.vlds = {}
         self.conf_prims = []
         self.scale_grps = []
         self.initial_cfg = []
+        self.placement_groups = []
+        self.vnf_id_to_vnf_map = {}
+        self.vnfd_files = vnfd_files
+        self.vld_to_vnf_map = {}
+        self.vnf_to_vld_map = {}
+        self._vnf_vld_conn_point_map = {}
 
     def handle_yang(self, vnfds):
         self.log.debug(_("Process NSD desc {0}: {1}").
@@ -85,6 +92,7 @@ class YangNsd(ToscaResource):
             vnfd_id = cvnfd.pop(self.VNFD_ID_REF)
             for vnfd in vnfds:
                 if vnfd.type == self.VNFD and vnfd.id == vnfd_id:
+                    self.vnf_id_to_vnf_map[vnfd_id] = vnfd.name
                     self.vnfds[cvnfd.pop(self.MEM_VNF_INDEX)] = vnfd
                     if self.START_BY_DFLT in cvnfd:
                         vnfd.props[self.START_BY_DFLT] = \
@@ -160,7 +168,82 @@ class YangNsd(ToscaResource):
                 self.log.warn(_("{0}, Did not process all fields for {1}").
                               format(self, dic))
             self.log.debug(_("{0}, Initial config {1}").format(self, icp))
-            self.initial_cfg.append(icp)
+            self.initial_cfg.append({self.PROPERTIES : icp})
+
+        def process_vld(vld, dic):
+            vld_conf = {}
+            vld_prop = {}
+            ip_profile_vld = None
+            vld_name = None
+            if 'ip_profile_ref' in vld:
+                ip_profile_name  = vld['ip_profile_ref']
+                if 'ip_profiles' in dic:
+                    for ip_prof in dic['ip_profiles']:
+                        if ip_profile_name == ip_prof['name']:
+                            ip_profile_vld = ip_prof
+            if 'name' in vld:
+                vld_name = vld['name']
+            if 'description' in vld:
+                vld_conf['description'] = vld['description']
+            if 'vendor' in vld:
+                vld_conf['vendor'] = vld['vendor']
+            if ip_profile_vld:
+                if 'ip_profile_params' in ip_profile_vld:
+                    ip_param = ip_profile_vld['ip_profile_params']
+                    if 'gateway_address' in ip_param:
+                        vld_conf['gateway_ip'] = ip_param['gateway_address']
+                    if 'subnet_address' in ip_param:
+                        vld_conf['cidr'] = ip_param['subnet_address']
+                    if 'ip_version' in ip_param:
+                        vld_conf['ip_version'] = ip_param['ip_version'].replace('ipv','')
+
+            if vld_name:
+                vld_prop = {vld_name :
+                {
+                 'type': self.T_ELAN,
+                 self.PROPERTIES : vld_conf
+                }}
+                self.vlds[vld_name] = { 'type': self.T_ELAN,
+                                         self.PROPERTIES : vld_conf
+                                        }
+
+                self.vld_to_vnf_map[vld_name] = []
+                if 'vnfd_connection_point_ref' in vld:
+                    for vnfd_ref in vld['vnfd_connection_point_ref']:
+                        vnf_name = self.vnf_id_to_vnf_map[vnfd_ref['vnfd_id_ref']]
+                        if vnf_name in self.vnf_to_vld_map:
+                            self.vnf_to_vld_map[vnf_name].append(vld_name)
+                            self._vnf_vld_conn_point_map[vnf_name].\
+                            append((vld_name ,vnfd_ref['vnfd_connection_point_ref']))
+                        else:
+                            self.vnf_to_vld_map[vnf_name] = []
+                            self._vnf_vld_conn_point_map[vnf_name] = []
+                            self.vnf_to_vld_map[vnf_name].append(vld_name)
+                            self._vnf_vld_conn_point_map[vnf_name].\
+                            append((vld_name ,vnfd_ref['vnfd_connection_point_ref']))
+
+        def process_placement_group(placement_groups):
+            for i in range(0, len(placement_groups)):
+                placement_group = placement_groups[i]
+                pg_name = "placement_{0}".format(i)
+                pg_config = {}
+                targets = []
+                if 'name' in placement_group:
+                    pg_config['name'] = placement_group['name']
+                if 'requirement' in placement_group:
+                    pg_config['requirement'] = placement_group['requirement']
+                if 'strategy' in placement_group:
+                    pg_config['strategy'] = placement_group['strategy']
+                if 'member_vnfd' in placement_group:
+                    for member_vnfd in placement_group['member_vnfd']:
+                        targets.append(self.vnf_id_to_vnf_map[member_vnfd['vnfd_id_ref']])
+                placement = { pg_name : {
+                                'type': self.T_PLACEMENT,
+                                self.PROPERTIES: pg_config,
+                                self.TARGETS   :  str(targets)
+                                }
+                            }
+                self.placement_groups.append(placement)
 
         dic = deepcopy(self.yang)
         try:
@@ -177,10 +260,8 @@ class YangNsd(ToscaResource):
             # Process VLDs
             if self.VLD in dic:
                 for vld_dic in dic.pop(self.VLD):
-                    vld = YangVld(self.log, vld_dic.pop(self.NAME),
-                                  self.VLD, vld_dic)
-                    vld.process_vld(self.vnfds)
-                    self.vlds.append(vld)
+                    process_vld(vld_dic, dic)
+                    #self.vlds.append(vld)
 
             # Process config primitives
             if self.CONF_PRIM in dic:
@@ -212,6 +293,10 @@ class YangNsd(ToscaResource):
                 for param in dic.pop(self.INPUT_PARAM_XPATH):
                     process_input_param(param)
 
+            if 'placement_groups' in dic:
+                process_placement_group(dic['placement_groups'])
+
+
             self.remove_ignored_fields(dic)
             if len(dic):
                 self.log.warn(_("{0}, Did not process the following for "
@@ -226,13 +311,14 @@ class YangNsd(ToscaResource):
             raise ValidationError(message=err_msg)
 
     def generate_tosca_type(self):
+
         self.log.debug(_("{0} Generate tosa types").
                        format(self))
 
         tosca = {}
-        tosca[self.DATA_TYPES] = {}
-        tosca[self.NODE_TYPES] = {}
-
+        #tosca[self.DATA_TYPES] = {}
+        #tosca[self.NODE_TYPES] = {}
+        return tosca
         for idx, vnfd in self.vnfds.items():
             tosca = vnfd.generate_tosca_type(tosca)
 
@@ -287,20 +373,25 @@ class YangNsd(ToscaResource):
     def generate_tosca_template(self, tosca):
         self.log.debug(_("{0}, Generate tosca template").
                        format(self, tosca))
-
         # Add the standard entries
         tosca['tosca_definitions_version'] = \
-                                    'tosca_simple_profile_for_nfv_1_0_0'
+                                    'tosca_simple_profile_for_nfv_1_0'
         tosca[self.DESC] = self.props[self.DESC]
         tosca[self.METADATA] = {
             'ID': self.name,
             self.VENDOR: self.props[self.VENDOR],
             self.VERSION: self.props[self.VERSION],
         }
+        if len(self.vnfd_files) > 0:
+            tosca[self.IMPORT] = []
+            imports = []
+            for vnfd_file in self.vnfd_files:
+                tosca[self.IMPORT].append('"{0}.yaml"'.format(vnfd_file))
 
         tosca[self.TOPOLOGY_TMPL] = {}
 
         # Add input params
+        '''
         if len(self.inputs):
             if self.INPUTS not in tosca[self.TOPOLOGY_TMPL]:
                 tosca[self.TOPOLOGY_TMPL][self.INPUTS] = {}
@@ -309,15 +400,38 @@ class YangNsd(ToscaResource):
                                           self.DESC:
                                           'Translated from YANG'}}
                 tosca[self.TOPOLOGY_TMPL][self.INPUTS] = entry
-
+        '''
         tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL] = {}
 
         # Add the VNFDs and VLDs
         for idx, vnfd in self.vnfds.items():
-            vnfd.generate_vnf_template(tosca, idx)
+            #vnfd.generate_vnf_template(tosca, idx)
+            node = {
+              'type' : vnfd.vnf_type,
+              self.PROPERTIES : {
+                self.ID : idx,
+                self.VENDOR : self.props[self.VENDOR],
+                self.VERSION : self.props[self.VERSION]
+              }
+            }
+            if vnfd.name in self.vnf_to_vld_map:
+                vld_list = self.vnf_to_vld_map[vnfd.name]
+                node[self.REQUIREMENTS] = []
+                for vld_idx in range(0, len(vld_list)):
+                    vld_link_name = "{0}{1}".format("virtualLink", vld_idx + 1)
+                    vld_prop = {}
+                    vld_prop[vld_link_name] = vld_list[vld_idx]
+                    node[self.REQUIREMENTS].append(vld_prop)
+                    if vnfd.name in self._vnf_vld_conn_point_map:
+                        vnf_vld_list = self._vnf_vld_conn_point_map[vnfd.name]
+                        for vnf_vld in vnf_vld_list:
+                            vnfd.generate_vld_link(vld_link_name, vnf_vld[1])
 
-        for vld in self.vlds:
-            vld.generate_tosca_template(tosca)
+
+            tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vnfd.name] = node
+
+        for vld_node_name in self.vlds:
+            tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vld_node_name] = self.vlds[vld_node_name]
 
         # add the config primitives
         if len(self.conf_prims):
@@ -361,33 +475,38 @@ class YangNsd(ToscaResource):
                 tosca[self.TOPOLOGY_TMPL][self.POLICIES] = []
 
             for icp in self.initial_cfg:
-                icpt = {
-                    self.TYPE: self.T_INITIAL_CFG,
-                }
-                icpt.update(icp)
-                tosca[self.TOPOLOGY_TMPL][self.POLICIES].append({
-                    self.INITIAL_CFG: icpt
-                })
+                if len(tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL]) > 0:
+                    node_name = list(tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL].keys())[0]
+                    icpt = {
+                        self.TYPE: self.T_INITIAL_CFG,
+                        self.TARGETS : "[{0}]".format(node_name)
+                    }
+                    icpt.update(icp)
+                    tosca[self.TOPOLOGY_TMPL][self.POLICIES].append({
+                        self.INITIAL_CFG: icpt
+                    })
+
+        if len(self.placement_groups) > 0:
+            if self.POLICIES not in tosca[self.TOPOLOGY_TMPL]:
+                tosca[self.TOPOLOGY_TMPL][self.POLICIES] = []
+
+            for placment_group in self.placement_groups:
+                tosca[self.TOPOLOGY_TMPL][self.POLICIES].append(placment_group)
 
         return tosca
 
     def get_supporting_files(self):
         files = []
-
-        for vnfd in self.vnfds.values():
-            f = vnfd.get_supporting_files()
-            if f and len(f):
-                files.extend(f)
-
         # Get the config files for initial config
         for icp in self.initial_cfg:
-            if self.USER_DEF_SCRIPT in icp:
-                script = os.path.basename(icp[self.USER_DEF_SCRIPT])
-                files.append({
-                    self.TYPE: 'script',
-                    self.NAME: script,
-                    self.DEST: "{}/{}".format(self.SCRIPT_DIR, script),
-                })
+            if 'properties' in icp:
+                if 'user_defined_script' in icp['properties']:
+                    script = os.path.basename(icp['properties']['user_defined_script'])
+                    files.append({
+                        self.TYPE: 'script',
+                        self.NAME: script,
+                        self.DEST: "{}/{}".format(self.SCRIPT_DIR, script),
+                    })
 
         # TODO (pjoseph): Add support for config scripts,
         # charms, etc
index 7d095c1..3786d86 100644 (file)
@@ -56,6 +56,15 @@ class YangVdu(ToscaResource):
         'storage_gb': ' GB',
     }
 
+    TOSCA_MEM_SIZE = {
+        'LARGE': 'huge',
+        'SMALL': 'normal',
+        'SIZE_2MB': 'size_2MB',
+        'SIZE_1GB': 'size_1GB',
+        'PREFER_LARGE': 'prefer_huge'
+
+    }
+
     def __init__(self,
                  log,
                  name,
@@ -69,8 +78,15 @@ class YangVdu(ToscaResource):
         self.props = {}
         self.ext_cp = []
         self.int_cp = []
-        self.image = None
+        self.image           = None
         self.cloud_init_file = None
+        self.host_epa        = None
+        self.vswitch_epa     = None
+        self.hypervisor_epa  = None
+        self.guest_epa       = None
+        self.cp_name_to_cp_node = {}
+        self.pinning_epa_prop   = {}
+        self.mem_page_guest_epa = None
 
     def process_vdu(self):
         self.log.debug(_("Process VDU desc {0}: {1}").format(self.name,
@@ -88,9 +104,9 @@ class YangVdu(ToscaResource):
         self.id = vdu[self.ID]
 
         if self.VM_FLAVOR in vdu_dic:
-            vdu[self.HOST] = {}
+            vdu[self.NFV_COMPUTE] = {}
             for key, value in vdu_dic.pop(self.VM_FLAVOR).items():
-                vdu[self.HOST][self.VM_FLAVOR_MAP[key]] = "{}{}". \
+                vdu[self.NFV_COMPUTE][self.VM_FLAVOR_MAP[key]] = "{}{}". \
                             format(value, self.VM_SIZE_UNITS_MAP[key])
 
         if self.EXT_INTF in vdu_dic:
@@ -103,7 +119,110 @@ class YangVdu(ToscaResource):
                                format(self, cp, ext_intf))
                 self.ext_cp.append(cp)
 
+        if self.HOST_EPA in vdu_dic:
+            host_epa = vdu_dic.pop(self.HOST_EPA)
+            host_epa_prop = {}
+            self.host_epa = host_epa
+            '''
+            if 'cpu_model' in host_epa:
+                host_epa_prop['cpu_model'] = host_epa['cpu_model'].lower()
+            if 'cpu_arch' in host_epa:
+                host_epa_prop['cpu_arch'] = host_epa['cpu_arch'].lower()
+            if 'cpu_vendor' in host_epa:
+                host_epa_prop['cpu_vendor'] = host_epa['cpu_vendor'].lower()
+            if 'cpu_socket_count' in host_epa:
+                host_epa_prop['cpu_socket_count'] = host_epa['cpu_socket_count']
+            if 'cpu_core_count' in host_epa:
+                host_epa_prop['cpu_core_count'] = host_epa['cpu_core_count']
+            if 'cpu_core_thread_count' in host_epa:
+                host_epa_prop['cpu_core_thread_count'] = host_epa['cpu_core_thread_count']
+            if 'om_cpu_model_string' in host_epa:
+                host_epa_prop['om_cpu_model_string'] = host_epa['om_cpu_model_string']
+            if 'cpu_feature' in host_epa:
+                host_epa_prop['cpu_feature'] = []
+                for cpu_feature in host_epa['cpu_feature']:
+                    cpu_feature_prop = {}
+                    cpu_feature_prop['feature'] = cpu_feature['feature'].lower()
+                    host_epa_prop['cpu_feature'] .append(cpu_feature_prop)
+
+            if 'om_cpu_feature' in host_epa:
+                host_epa_prop['om_cpu_feature'] = []
+                for cpu_feature in host_epa['om_cpu_feature']:
+                    om_cpu_feature_prop = {}
+                    om_cpu_feature_prop['feature'] = cpu_feature
+                    host_epa_prop['om_cpu_feature'].append(om_cpu_feature_prop)
+            self.host_epa = host_epa
+            '''
+        # We might have to re write this piece of code, there are mismatch in 
+        # enum names. Its all capital in RIFT yang and TOSCA
+        if self.VSWITCH_EPA in vdu_dic:
+            vswitch_epa = vdu_dic.pop(self.VSWITCH_EPA)
+            self.vswitch_epa = vswitch_epa
+        if self.HYPERVISOR_EPA in vdu_dic:
+            hypervisor_epa = vdu_dic.pop(self.HYPERVISOR_EPA)
+            hypervisor_epa_prop = {}
+
+            if 'type_yang' in hypervisor_epa:
+                hypervisor_epa_prop['type'] = hypervisor_epa['type_yang']
+            if 'version' in hypervisor_epa:
+                hypervisor_epa_prop['version'] = str(hypervisor_epa['version'])
+            else:
+                hypervisor_epa_prop['version'] = '1'
+            self.hypervisor_epa = hypervisor_epa_prop
+
+        if self.GUEST_EPA in vdu_dic:
+            guest_epa = vdu_dic[self.GUEST_EPA]
+            guest_epa_prop = {}
+
+            # This is a hack. I have to rewrite this. I have got this quick to working
+            # 'ANY' check should be added in riftio common file. Its not working for some reason. Will fix.
+
+            if 'cpu_pinning_policy' in guest_epa and guest_epa['cpu_pinning_policy'] != 'ANY':
+                self.pinning_epa_prop['cpu_affinity'] = guest_epa['cpu_pinning_policy'].lower()
+            if 'cpu_thread_pinning_policy' in guest_epa:
+                 self.pinning_epa_prop['thread_allocation'] = guest_epa['cpu_thread_pinning_policy'].lower()
+            if 'mempage_size'  in guest_epa:
+                self.mem_page_guest_epa = self.TOSCA_MEM_SIZE[guest_epa['mempage_size']]
+
+            if 'numa_node_policy' in guest_epa:
+                num_node_policy = guest_epa['numa_node_policy']
+                if 'node_cnt' in num_node_policy:
+                    guest_epa_prop['node_cnt'] = num_node_policy['node_cnt']
+                if 'mem_policy' in num_node_policy:
+                    guest_epa_prop['mem_policy'] = num_node_policy['mem_policy']
+                if 'node' in num_node_policy:
+                    nodes = []
+                    for node in num_node_policy['node']:
+                        node_prop = {}
+                        if 'id' in node:
+                            node_prop['id'] = node['id']
+                        if 'vcpu' in node:
+                            vc =[]
+                            for vcp in node['vcpu']:
+                                vc.append(vcp['id'])
+
+                            node_prop['vcpus'] = vc
+                        if 'memory_mb' in  node:
+                            node_prop['mem_size'] = "{} MB".format(node['memory_mb'])
+                        # om_numa_type generation
+
+                        if 'num_cores' in node:
+                            node_prop['om_numa_type'] = 'num_cores'
+                            node_prop['num_cores'] = node['num_cores']
+                        elif 'paired_threads' in node:
+                            node_prop['om_numa_type'] = 'paired-threads'
+                            node_prop['paired_threads'] = node['paired_threads']
+                        elif 'threads]' in node:
+                            node_prop['om_numa_type'] = 'threads]'
+                            node_prop['num_thread]'] = node['threads]']
+
+                        nodes.append(node_prop)
+                    guest_epa_prop['node'] = nodes
+
+            self.guest_epa = guest_epa_prop
+
         self.remove_ignored_fields(vdu_dic)
+
         if len(vdu_dic):
             self.log.warn(_("{0}, Did not process the following in "
                             "VDU: {1}").
@@ -151,6 +270,7 @@ class YangVdu(ToscaResource):
         # Create a unique name incase multiple VNFs use same
         # name for the vdu
         return "{}_{}".format(vnf_name, self.name)
+        #return self.name
 
     def generate_tosca_type(self, tosca):
         self.log.debug(_("{0} Generate tosa types").
@@ -218,14 +338,35 @@ class YangVdu(ToscaResource):
 
         node = {}
         node[self.TYPE] = self.T_VDU1
+        node[self.CAPABILITIES] = {}
 
-        if self.HOST in self.props:
-            node[self.CAPABILITIES] = {
-                self.HOST: {self.PROPERTIES: self.props.pop(self.HOST)}
-            }
+        if self.NFV_COMPUTE in self.props:
+            node[self.CAPABILITIES][self.NFV_COMPUTE] = {self.PROPERTIES: self.props.pop(self.NFV_COMPUTE)}
         else:
             self.log.warn(_("{0}, Does not have host requirements defined").
                           format(self))
+        if self.host_epa:
+            node[self.CAPABILITIES][self.HOST_EPA] = {
+                self.PROPERTIES: self.host_epa
+            }
+        if self.vswitch_epa:
+            node[self.CAPABILITIES][self.VSWITCH_EPA] = {
+                self.PROPERTIES: self.vswitch_epa
+            }
+        if self.hypervisor_epa:
+            node[self.CAPABILITIES][self.HYPERVISOR_EPA] = {
+                self.PROPERTIES: self.hypervisor_epa
+            }
+        if self.guest_epa:
+            node[self.CAPABILITIES]['numa_extension'] = {
+                self.PROPERTIES: self.guest_epa
+            }
+        if len(self.pinning_epa_prop) > 0:
+            if node[self.CAPABILITIES][self.NFV_COMPUTE] and node[self.CAPABILITIES][self.NFV_COMPUTE][self.PROPERTIES]:
+                node[self.CAPABILITIES][self.NFV_COMPUTE][self.PROPERTIES]['cpu_allocation'] = self.pinning_epa_prop
+        if self.mem_page_guest_epa:
+            if node[self.CAPABILITIES][self.NFV_COMPUTE] and node[self.CAPABILITIES][self.NFV_COMPUTE][self.PROPERTIES]:
+                node[self.CAPABILITIES][self.NFV_COMPUTE][self.PROPERTIES]['mem_page_size'] = self.mem_page_guest_epa
 
         if self.IMAGE in self.props:
             img_name = "{}_{}_vm_image".format(vnf_name, self.name)
@@ -241,10 +382,22 @@ class YangVdu(ToscaResource):
             node[self.INTERFACES] = {'Standard': {
                 'create': img_name
             }}
-
         # Add cloud init script if available
         if self.CLOUD_INIT_FILE in self.props:
+            cloud_name = "{}_{}_cloud_init".format(vnf_name, self.name)
             self.cloud_init_file = self.props[self.CLOUD_INIT_FILE]
+            cloud_init_file = "../{}/{}".format(self.CLOUD_INIT_DIR, self.props.pop(self.CLOUD_INIT_FILE))
+            if self.ARTIFACTS in node:
+               node[self.ARTIFACTS][cloud_name] = {
+               self.FILE: cloud_init_file,
+               self.TYPE: self.T_ARTF_CLOUD_INIT,
+               }
+            else:
+                node[self.ARTIFACTS] = {
+                cloud_name: {
+                self.FILE: cloud_init_file,
+                self.TYPE: self.T_ARTF_CLOUD_INIT,
+                }}
 
         # Remove
         self.props.pop(self.ID)
@@ -269,6 +422,7 @@ class YangVdu(ToscaResource):
 
             cpt[self.PROPERTIES] = cp
             cp_name = cp[self.NAME].replace('/', '_')
+            self.cp_name_to_cp_node[cp[self.NAME]] = cp_name
 
             self.log.debug(_("{0}, CP node {1}: {2}").
                            format(self, cp_name, cpt))
@@ -296,7 +450,5 @@ class YangVdu(ToscaResource):
             })
 
         self.log.debug(_("Supporting files for {} : {}").format(self, files))
-        if not len(files):
-            shutil.rmtree(out_dir)
 
         return files
index 9ff53e2..1094c14 100644 (file)
@@ -33,6 +33,7 @@ class YangVnfd(ToscaResource):
 
     OTHER_KEYS = (MGMT_INTF, HTTP_EP, MON_PARAM) = \
                  ('mgmt_interface', 'http_endpoint', 'monitoring_param')
+    vnf_prefix_type = 'tosca.nodes.nfv.riftio.'
 
 
     def __init__(self,
@@ -49,6 +50,12 @@ class YangVnfd(ToscaResource):
         self.mgmt_intf = {}
         self.mon_param = []
         self.http_ep = []
+        self.vnf_configuration = None
+        self.monitor_param = {}
+        self.monitor_param_1 = {}
+        self.vnf_type = None
+        self.tosca = None
+        self.script_files = []
 
     def handle_yang(self):
         self.log.debug(_("Process VNFD desc {0}: {1}").format(self.name,
@@ -56,28 +63,45 @@ class YangVnfd(ToscaResource):
 
         def process_vnf_config(conf):
             vnf_conf = {}
-            if self.CONFIG_ATTR in conf:
-                for key, value in conf.pop(self.CONFIG_ATTR).items():
-                    vnf_conf[key] = value
-
-            if self.CONFIG_TMPL in conf:
-                vnf_conf[self.CONFIG_TMPL] = conf.pop(self.CONFIG_TMPL)
-
-            def copy_config_details(conf_type, conf_details):
-                vnf_conf[self.CONFIG_TYPE] = conf_type
-                vnf_conf[self.CONFIG_DETAILS] = conf_details
-
-            for key in self.CONFIG_TYPES:
-                if key in conf:
-                    copy_config_details(key, conf.pop(key))
-                    break
-
-            if len(conf):
-                self.log.warn(_("{0}, Did not process all in VNF "
-                                "configuration {1}").
-                              format(self, conf))
-            self.log.debug(_("{0}, vnf config: {1}").format(self, vnf_conf))
-            self.props[self.VNF_CONFIG] = vnf_conf
+            config = {}
+
+            init_primitive_config = {}
+            if 'config_template' in conf:
+                config['config_template'] = conf['config_template']
+            if 'config_attributes' in conf:
+                if 'config_delay' in conf['config_attributes']:
+                    config['config_delay'] = conf['config_attributes']['config_delay']
+                if 'config_priority' in conf['config_attributes']:
+                    config['config_priority'] = conf['config_attributes']['config_priority']
+            if 'config_type' in conf:
+                config['config_type'] = conf['config_type']
+            if 'script' in conf:
+                config['config_details'] = conf['script']
+            for conf_type in self.CONFIG_TYPES:
+                if conf_type in conf:
+                    config['config_type'] = conf_type
+            if len(config) > 0:
+                vnf_conf['config'] = config
+
+            if 'initial_config_primitive' in conf:
+                init_config_prims = []
+                for init_conf_prim in conf['initial_config_primitive']:
+                    init_conf = {}
+                    if 'name' in init_conf_prim:
+                        init_conf['name'] = init_conf_prim['name']
+                    if 'seq' in init_conf_prim:
+                        init_conf['seq'] = init_conf_prim['seq']
+                    if 'user_defined_script' in init_conf_prim:
+                        init_conf['user_defined_script'] = init_conf_prim['user_defined_script']
+                        self.script_files.append(init_conf_prim['user_defined_script'])
+                    if 'parameter' in init_conf_prim:
+                        init_conf['parameter'] = []
+                        for parameter in init_conf_prim['parameter']:
+                            init_conf['parameter'].append({parameter['name']: parameter['value']})
+                    init_config_prims.append(init_conf)
+                vnf_conf['initial_config_primitive'] = init_config_prims
+
+            self.vnf_configuration = vnf_conf
 
         def process_mgmt_intf(intf):
             if len(self.mgmt_intf) > 0:
@@ -131,16 +155,34 @@ class YangVnfd(ToscaResource):
                 fields = [self.NAME, self.ID, 'value_type', 'units', 'group_tag',
                           'json_query_method', 'http_endpoint_ref', 'widget_type',
                           self.DESC]
-                for key in fields:
-                    if key in param:
-                        monp[key] = param.pop(key)
+                mon_param = {}
+                ui_param = {}
+                if 'name' in param:
+                    mon_param['name'] = param['name']
+                if 'description' in param:
+                    mon_param['description'] = param['description']
+                if 'polling_interval' in param:
+                    mon_param['polling_interval'] = param['polling_interval']
+                if 'http_endpoint_ref' in param:
+                    mon_param['url_path'] = param['http_endpoint_ref']
+                if 'json_query_method' in param:
+                    mon_param['json_query_method'] = param['json_query_method'].lower()
+                if 'group_tag' in param:
+                    ui_param['group_tag'] = param['group_tag']
+                if 'widget_type' in param:
+                    ui_param['widget_type'] = param['widget_type'].lower()
+                if 'units'  in param:
+                    ui_param['units'] = param['units']
+                mon_param['ui_data'] = ui_param
+
+                self.mon_param.append(mon_param)
 
                 if len(param):
                     self.log.warn(_("{0}, Did not process the following for "
                                     "monitporing-param {1}").
                                   format(self, param))
                     self.log.debug(_("{0}, Monitoring param: {1}").format(self, monp))
-                self.mon_param.append(monp)
+                #self.mon_param.append(monp)
 
         def process_cp(cps):
             for cp_dic in cps:
@@ -161,7 +203,6 @@ class YangVnfd(ToscaResource):
             self.MON_PARAM: process_mon_param,
             'connection_point': process_cp
         }
-
         dic = deepcopy(self.yang)
         try:
             for key in self.REQUIRED_FIELDS:
@@ -177,11 +218,9 @@ class YangVnfd(ToscaResource):
                                   self.VDU, vdu_dic)
                     vdu.process_vdu()
                     self.vdus.append(vdu)
-
             for key in ENDPOINTS_MAP.keys():
                 if key in dic:
                     ENDPOINTS_MAP[key](dic.pop(key))
-
             if self.VNF_CONFIG in dic:
                 process_vnf_config(dic.pop(self.VNF_CONFIG))
 
@@ -203,135 +242,53 @@ class YangVnfd(ToscaResource):
             if cp:
                 vdu.set_vld(cp_name, vld_name)
                 break
-
-    def generate_tosca_type(self, tosca):
-        self.log.debug(_("{0} Generate tosa types").
-                       format(self))
-
-        for vdu in self.vdus:
-            tosca = vdu.generate_tosca_type(tosca)
-
-        # Add data_types
-        if self.T_VNF_CONFIG not in tosca[self.DATA_TYPES]:
-            tosca[self.DATA_TYPES][self.T_VNF_CONFIG] = {
-                self.PROPERTIES:
-                {self.CONFIG_TYPE:
-                 {self.TYPE: self.STRING},
-                 'config_delay':
-                 {self.TYPE: self.INTEGER,
-                  self.DEFAULT: 0,
-                  self.REQUIRED: self.NO,
-                  self.CONSTRAINTS:
-                  [{'greater_or_equal': 0}]},
-                 'config_priority':
-                 {self.TYPE: self.INTEGER,
-                  self.CONSTRAINTS:
-                  [{'greater_than': 0}]},
-                 self.CONFIG_DETAILS:
-                 {self.TYPE: self.MAP},
-                 self.CONFIG_TMPL:
-                 {self.TYPE: self.STRING,
-                  self.REQUIRED: self.NO},
-                }
-            }
-
-        # Add capability types
-        if self.CAPABILITY_TYPES not in tosca:
-            tosca[self.CAPABILITY_TYPES] = {}
-        if self.T_HTTP_EP not in tosca[self.CAPABILITY_TYPES]:
-            tosca[self.CAPABILITY_TYPES][self.T_HTTP_EP] = {
-                self.DERIVED_FROM: 'tosca.capabilities.Endpoint',
-                self.PROPERTIES: {
-                    'polling_interval':
-                    {self.TYPE: self.INTEGER},
-                    'path':
-                    {self.TYPE: self.STRING},
-                },
-            }
-
-        if self.T_MGMT_INTF not in tosca[self.CAPABILITY_TYPES]:
-            tosca[self.CAPABILITY_TYPES][self.T_MGMT_INTF] = {
-                self.DERIVED_FROM: 'tosca.capabilities.Endpoint',
-                self.PROPERTIES: {
-                    self.DASHBOARD_PARAMS:
-                    {self.TYPE: self.MAP},
-                    self.VDU:
-                    {self.TYPE: self.STRING},
-                },
-            }
-
-        if self.T_MON_PARAM not in tosca[self.CAPABILITY_TYPES]:
-            tosca[self.CAPABILITY_TYPES][self.T_MON_PARAM] = {
-                self.DERIVED_FROM: 'tosca.capabilities.nfv.Metric',
-                self.PROPERTIES: {
-                    'id':
-                    {self.TYPE: self.INTEGER},
-                    'name':
-                    {self.TYPE: self.STRING},
-                    'value_type':
-                    {self.TYPE: self.STRING,
-                     self.DEFAULT: 'INT'},
-                    'group_tag':
-                    {self.TYPE: self.STRING,
-                     self.DEFAULT: 'Group1'},
-                    'units':
-                    {self.TYPE: self.STRING},
-                    'description':
-                    {self.TYPE: self.STRING},
-                    'json_query_method':
-                    {self.TYPE: self.STRING,
-                     self.DEFAULT: 'NAMEKEY'},
-                    'http_endpoint_ref':
-                    {self.TYPE: self.STRING},
-                    'widget_type':
-                    {self.TYPE: self.STRING,
-                     self.DEFAULT: 'COUNTER'},
-                }
+    def _generate_vnf_type(self, tosca):
+        name = self.name.split('_', 1)[0]
+        self.vnf_type = "{0}{1}{2}".format(self.vnf_prefix_type, name, 'VNF')
+        if self.NODE_TYPES not in tosca and self.vnf_type:
+            tosca[self.NODE_TYPES] = {}
+            tosca[self.NODE_TYPES][self.vnf_type] = {
+            self.DERIVED_FROM : self.T_VNF1
             }
 
-        # Define the VNF type
-        if self.T_VNF1 not in tosca[self.NODE_TYPES]:
-            tosca[self.NODE_TYPES][self.T_VNF1] = {
-                self.DERIVED_FROM: 'tosca.nodes.nfv.VNF',
-                self.PROPERTIES: {
-                    'vnf_configuration':
-                    {self.TYPE: self.T_VNF_CONFIG},
-                    'port':
-                    {self.TYPE: self.INTEGER,
-                     self.CONSTRAINTS:
-                     [{'in_range': '[1, 65535]'}]},
-                    self.START_BY_DFLT:
-                    {self.TYPE: self.BOOL,
-                     self.DEFAULT: self.TRUE},
-                },
-                self.CAPABILITIES: {
-                    'mgmt_interface':
-                    {self.TYPE: self.T_MGMT_INTF},
-                    'http_endpoint':
-                    {self.TYPE: self.T_HTTP_EP},
-                    'monitoring_param_0':
-                    {self.TYPE: self.T_MON_PARAM},
-                    'monitoring_param_1':
-                    {self.TYPE: self.T_MON_PARAM},
-                },
-                self.REQUIREMENTS: [
-                    {'vdus':
-                     {self.TYPE: 'tosca.capabilities.nfv.VirtualLinkable',
-                      self.RELATIONSHIP:
-                      'tosca.relationships.nfv.VirtualLinksTo',
-                      self.NODE: self.T_VDU1,
-                      self.OCCURENCES: '[1, UNBOUND]'}}
-                ],
-            }
+    def generate_tosca_template(self, tosca):
+        self.tosca = tosca
+        tosca['tosca_definitions_version'] = 'tosca_simple_profile_for_nfv_1_0'
+        tosca[self.IMPORT] = []
+        tosca[self.IMPORT].append("riftiotypes.yaml")
+        tosca[self.DESC] = self.props[self.DESC]
+        tosca[self.METADATA] = {
+            'ID': self.name,
+            self.VENDOR: self.props[self.VENDOR],
+            self.VERSION: self.props[self.VERSION],
+        }
+        if self.name:
+            self._generate_vnf_type(tosca);
 
-        return tosca
 
-    def generate_vnf_template(self, tosca, index):
-        self.log.debug(_("{0}, Generate tosca template for VNF {1}").
-                       format(self, index, tosca))
+        tosca[self.TOPOLOGY_TMPL] = {}
+        tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL] = {}
+        tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING] = {}
+        tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING]['node_type'] = self.vnf_type
 
         for vdu in self.vdus:
-            tosca = vdu.generate_vdu_template(tosca, self.name)
+            vdu.generate_vdu_template(tosca, self.name)
+            if 'vdu' in self.mgmt_intf and self.mgmt_intf['vdu'] == vdu.get_name(self.name): #TEST
+                mgmt_interface = {}
+                mgmt_interface[self.PROPERTIES] = self.mgmt_intf
+                self.mgmt_intf.pop('vdu')
+                caps = []
+                tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vdu.get_name(self.name)][self.CAPABILITIES]['mgmt_interface'] = mgmt_interface #TEST
+                if len(self.mon_param) > 0:
+                    mon_param = {}
+                    mon_param = {}
+                    mon_param['properties'] = self.mon_param[0]
+                    tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vdu.get_name(self.name)][self.CAPABILITIES]['monitoring_param'] = mon_param #TEST
+                if len(self.mon_param) == 2:
+                    mon_param = {}
+                    mon_param = {}
+                    mon_param['properties'] = self.mon_param[1]
+                    tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][vdu.get_name(self.name)][self.CAPABILITIES]['monitoring_param_1'] = mon_param
 
         node = {}
         node[self.TYPE] = self.T_VNF1
@@ -340,7 +297,9 @@ class YangVnfd(ToscaResource):
         self.props.pop(self.DESC)
 
         # Update index to the member-vnf-index
-        self.props[self.ID] = index
+
+        # For now I am putting index as 1. This needs to be revisted
+        self.props[self.ID] = 1
         node[self.PROPERTIES] = self.props
 
         caps = {}
@@ -379,16 +338,67 @@ class YangVnfd(ToscaResource):
 
         self.log.debug(_("{0}, VNF node: {1}").format(self, node))
 
-        tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][self.name] = node
+        #tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL][self.name] = node
+        self.get_vnf_configuration_policy(tosca)
+
+        return tosca
+
+    def generate_vld_link(self, virtualLink, conn_point):
+        if self.REQUIREMENTS not in self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING]:
+            self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING] = {}
+            self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING]['node_type'] = self.vnf_type
+            #self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING]['node_type'] = []
+            #self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING]['node_type'].\
+            #append(['node_type', self.vnf_type])
+            self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING][self.REQUIREMENTS] = []
+
+        for vdu in self.vdus:
+            if conn_point in vdu.cp_name_to_cp_node:
+                conn_point_node_name = vdu.cp_name_to_cp_node[conn_point]
+                self.tosca[self.TOPOLOGY_TMPL][self.SUBSTITUTION_MAPPING][self.REQUIREMENTS].\
+                    append({virtualLink : "[{0}, {1}]".format(conn_point_node_name, "virtualLink")})
+
+        if self.REQUIREMENTS not in self.tosca[self.NODE_TYPES][self.vnf_type]:
+            self.tosca[self.NODE_TYPES][self.vnf_type][self.REQUIREMENTS] = []
+        self.tosca[self.NODE_TYPES][self.vnf_type][self.REQUIREMENTS].append({virtualLink : {
+                                                                        "type": "tosca.nodes.nfv.VL"}})
 
+
+    def generate_tosca(self):
+        tosca = {}
         return tosca
 
+    def get_vnf_configuration_policy(self, tosca):
+        if self.vnf_configuration:
+            if self.POLICIES in tosca:
+                tosca[self.TOPOLOGY_TMPL][self.POLICIES]['configuration'] ={
+                'type' : self.T_VNF_CONFIG,
+                 self.PROPERTIES: self.vnf_configuration
+                }
+            else:
+                tosca[self.TOPOLOGY_TMPL][self.POLICIES] = []
+            # This is bad hack. TOSCA Openstack does not return policies without target
+            if len(tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL]) > 0:
+                node_name = list(tosca[self.TOPOLOGY_TMPL][self.NODE_TMPL].keys())[0]
+                tosca[self.TOPOLOGY_TMPL][self.POLICIES].append({'configuration' :{
+                 'type' : self.T_VNF_CONFIG,
+                 self.PROPERTIES: self.vnf_configuration,
+                 self.TARGETS : "[{0}]".format(node_name)
+                }})
+
     def get_supporting_files(self):
         files = []
+        for file in self.script_files:
+            files.append({
+                        self.TYPE: 'script',
+                        self.NAME: file,
+                        self.DEST: "{}/{}".format(self.SCRIPT_DIR, file),
+                    })
+
 
         for vdu in self.vdus:
-            f = vdu.get_supporting_files()
-            if f and len(f):
-                files.extend(f)
+            vdu_files = vdu.get_supporting_files()
+            for vdu_file in vdu_files:
+                files.append(vdu_file)
 
         return files
index 907a4a0..0919494 100644 (file)
@@ -48,24 +48,36 @@ class YangTranslator(object):
         self.tosca_template = ToscaTemplate(log)
         self.node_translator = None
         self.pkgs = packages
+        self.output_files = {}
+        self.output_files['nsd'] = []
+        self.output_files['vnfd'] = []
+
         log.info(_('Initialized parameters for translation.'))
 
     def translate(self):
         if self.files:
             self.get_yangs()
+        else:
+            if 'nsd' in self.yangs:
+                self.output_files['nsd'].append(self.yangs['nsd'][0]['short_name'])
+            if 'vnfd' in self.yangs:
+                for yang_vnfd in self.yangs['vnfd']:
+                    self.output_files['vnfd'].append(yang_vnfd['short_name'])
 
         self.node_translator = TranslateDescriptors(self.log,
                                                       self.yangs,
-                                                      self.tosca_template)
-
+                                                      self.tosca_template,
+                                                      self.output_files['vnfd'])
         self.tosca_template.resources = self.node_translator.translate()
 
+
         return self.tosca_template.output_to_tosca()
 
     def get_yangs(self):
         '''Get the descriptors and convert to yang instances'''
         for filename in self.files:
             self.log.debug(_("Load file {0}").format(filename))
+
             # Only one descriptor per file
             if tarfile.is_tarfile(filename):
                 tar = open(filename, "r+b")
@@ -78,36 +90,70 @@ class YangTranslator(object):
                         self.yangs[TranslateDescriptors.NSD] = []
                     self.yangs[TranslateDescriptors.NSD]. \
                         append(pkg.descriptor_msg.as_dict())
+                    if 'name' in pkg.descriptor_msg.as_dict() is not None:
+                        self.output_files['nsd'].append(pkg.descriptor_msg.as_dict()['name'])
+                    else:
+                        raise ValidationError(message="NSD Descriptor name attribute is not populated ")
                 elif desc_type == TranslateDescriptors.VNFD:
                     if TranslateDescriptors.VNFD not in self.yangs:
                         self.yangs[TranslateDescriptors.VNFD] = []
                     self.yangs[TranslateDescriptors.VNFD]. \
                         append(pkg.descriptor_msg.as_dict())
+                    if 'name' in pkg.descriptor_msg.as_dict() is not None:
+                        self.output_files['vnfd'].append(pkg.descriptor_msg.as_dict()['name'])
+                    else:
+                        raise ValidationError(message="VNFD Descriptor name attribute is not populated ")
                 else:
                     raise ValidationError("Unknown descriptor type: {}".
                                           format(desc_type))
 
-    def _create_csar_files(self, output_dir, name, tmpl,
+    def _create_csar_files(self, output_dir, tmpl_out,
                            archive=False):
-        if ToscaTemplate.TOSCA not in tmpl:
-            self.log.error(_("Did not find TOSCA template for {0}").
-                           format(name))
-            return
-
+        '''
+        for tmpl in tmpl_out:
+            if ToscaTemplate.TOSCA not in tmpl:
+                self.log.error(_("Did not find TOSCA template for {0}").
+                           format(tmpl))
+                return
+        '''
         # Create sub for each NS template
-        subdir = os.path.join(output_dir, name)
+        sub_folder_name = None
+        if self.files:
+            if len(self.output_files['nsd']) > 0:
+                if len(self.output_files['nsd']) == 1:
+                    sub_folder_name = self.output_files['nsd'][0]
+                else:
+                    raise ValidationError(message="Multiple NSD Descriptor uploaded ")
+            elif len(self.output_files['vnfd']) > 0:
+                if len(self.output_files['vnfd']) == 1:
+                    sub_folder_name = self.output_files['vnfd'][0]
+                else:
+                    raise ValidationError(message="Multiple VNFDs Descriptors uploaded without NSD")
+            else:
+                raise ValidationError(message="No NSD or VNFD uploaded")
+        else:
+            if 'nsd' in self.yangs:
+                sub_folder_name = self.yangs['nsd'][0]['short_name']
+            elif 'vnfd' in self.yangs:
+                sub_folder_name = self.yangs['vnfd'][0]['short_name']
+
+
+        subdir = os.path.join(output_dir, sub_folder_name)
         if os.path.exists(subdir):
             shutil.rmtree(subdir)
         os.makedirs(subdir)
-
+        riftio_src_file = "{0}{1}".format(os.getenv('RIFT_INSTALL'), "/usr/rift/mano/common/riftiotypes.yaml")
         # Create the definitions dir
         def_dir = os.path.join(subdir, 'Definitions')
         os.makedirs(def_dir)
-        entry_file = os.path.join(def_dir, name+'.yaml')
-        self.log.debug(_("Writing file {0}").
-                       format(entry_file))
-        with open(entry_file, 'w+') as f:
-            f.write(tmpl[ToscaTemplate.TOSCA])
+        shutil.copy2(riftio_src_file, def_dir + "/riftiotypes.yaml")
+        for tmpl_key in tmpl_out:
+            tmpl = tmpl_out[tmpl_key]
+            entry_file = os.path.join(def_dir, tmpl_key+'.yaml')
+            self.log.debug(_("Writing file {0}").
+                           format(entry_file))
+            with open(entry_file, 'w+') as f:
+                f.write(tmpl[ToscaTemplate.TOSCA])
 
         # Create the Tosca meta
         meta_dir = os.path.join(subdir, 'TOSCA-Metadata')
@@ -116,7 +162,7 @@ class YangTranslator(object):
 CSAR-Version: 1.1
 Created-By: RIFT.io
 Entry-Definitions: Definitions/'''
-        meta_data = "{}{}".format(meta, name+'.yaml')
+        meta_data = "{}{}".format(meta, sub_folder_name+'.yaml')
         meta_file = os.path.join(meta_dir, 'TOSCA.meta')
         self.log.debug(_("Writing file {0}:\n{1}").
                        format(meta_file, meta_data))
@@ -124,53 +170,55 @@ Entry-Definitions: Definitions/'''
             f.write(meta_data)
 
         # Copy other supporting files
-        if ToscaTemplate.FILES in tmpl:
-            for f in tmpl[ToscaTemplate.FILES]:
-                self.log.debug(_("Copy supporting file {0}").format(f))
-
-                # Search in source packages
-                if len(self.pkgs):
-                    for pkg in self.pkgs:
-                        # TODO(pjoseph): Need to add support for other file types
-                        fname = f[ToscaResource.NAME]
-                        dest_path = os.path.join(subdir, f[ToscaResource.DEST])
-                        ftype = f[ToscaResource.TYPE]
-
-                        if ftype == 'image':
-                            image_file_map = rift.package.image.get_package_image_files(pkg)
-
-                            if fname in image_file_map:
-                                self.log.debug(_("Extracting image {0} to {1}").
-                                               format(fname, dest_path))
-                                pkg.extract_file(image_file_map[fname],
-                                                 dest_path)
-                                break
-
-                        elif ftype == 'script':
-                            script_file_map = \
-                                rift.package.script.PackageScriptExtractor.package_script_files(pkg)
-                            if fname in script_file_map:
-                                self.log.debug(_("Extracting script {0} to {1}").
-                                               format(fname, dest_path))
-                                pkg.extract_file(script_file_map[fname],
-                                                 dest_path)
-                                break
-
-                        elif ftype == 'cloud_init':
-                            script_file_map = \
-                                rift.package.cloud_init.PackageCloudInitExtractor.package_script_files(pkg)
-                            if fname in script_file_map:
-                                self.log.debug(_("Extracting script {0} to {1}").
-                                               format(fname, dest_path))
-                                pkg.extract_file(script_file_map[fname],
-                                                 dest_path)
-                                break
-
-                        else:
-                            self.log.warn(_("Unknown file type {0}: {1}").
-                                          format(ftype, f))
-
-                #TODO(pjoseph): Search in other locations
+        for key in tmpl_out:
+            tmpl = tmpl_out[key]
+            if ToscaTemplate.FILES in tmpl:
+                for f in tmpl[ToscaTemplate.FILES]:
+                    self.log.debug(_("Copy supporting file {0}").format(f))
+
+                    # Search in source packages
+                    if len(self.pkgs):
+                        for pkg in self.pkgs:
+                            # TODO(pjoseph): Need to add support for other file types
+                            fname = f[ToscaResource.NAME]
+                            dest_path = os.path.join(subdir, f[ToscaResource.DEST])
+                            ftype = f[ToscaResource.TYPE]
+
+                            if ftype == 'image':
+                                image_file_map = rift.package.image.get_package_image_files(pkg)
+
+                                if fname in image_file_map:
+                                    self.log.debug(_("Extracting image {0} to {1}").
+                                                   format(fname, dest_path))
+                                    pkg.extract_file(image_file_map[fname],
+                                                     dest_path)
+                                    break
+
+                            elif ftype == 'script':
+                                script_file_map = \
+                                    rift.package.script.PackageScriptExtractor.package_script_files(pkg)
+                                if fname in script_file_map:
+                                    self.log.debug(_("Extracting script {0} to {1}").
+                                                   format(fname, dest_path))
+                                    pkg.extract_file(script_file_map[fname],
+                                                     dest_path)
+                                    break
+
+                            elif ftype == 'cloud_init':
+                                script_file_map = \
+                                    rift.package.cloud_init.PackageCloudInitExtractor.package_script_files(pkg)
+                                if fname in script_file_map:
+                                    self.log.debug(_("Extracting script {0} to {1}").
+                                                   format(fname, dest_path))
+                                    pkg.extract_file(script_file_map[fname],
+                                                     dest_path)
+                                    break
+
+                            else:
+                                self.log.warn(_("Unknown file type {0}: {1}").
+                                              format(ftype, f))
+
+                    #TODO(pjoseph): Search in other locations
 
         # Create the ZIP archive
         if archive:
@@ -178,7 +226,7 @@ Entry-Definitions: Definitions/'''
             os.chdir(subdir)
 
             try:
-                zip_file = name + '.zip'
+                zip_file = key + '.zip'
                 zip_path = os.path.join(output_dir, zip_file)
                 self.log.debug(_("Creating zip file {0}").format(zip_path))
                 zip_cmd = "zip -r {}.partial ."
@@ -207,14 +255,12 @@ Entry-Definitions: Definitions/'''
                      archive=False,):
         if output:
             zip_files = []
-            for key in output.keys():
-                if output_dir:
-                    zf = self._create_csar_files(output_dir,
-                                                 key,
-                                                 output[key],
-                                                 archive=archive,)
-                    zip_files.append(zf)
-                else:
-                    print(_("TOSCA Template {0}:\n{1}").
-                          format(key, output[key]))
+            #for key in output.keys():
+            if output_dir:
+                zf = self._create_csar_files(output_dir,
+                                             output,
+                                             archive=archive,)
+                zip_files.append(zf)
+            else:
+                print(_("There is an issue with TOSCA Template"))
             return zip_files
index 7fa6130..ff6a373 100644 (file)
@@ -326,11 +326,6 @@ class ExportRpcHandler(mano_dts.AbstractRpcHandler):
         if format_ != "yaml":
             log.warn("Only yaml format supported for TOSCA export")
 
-        if desc_type != "nsd":
-            raise tornado.web.HTTPError(
-                400,
-                "NSD need to passed to generate TOSCA: {}".format(desc_type))
-
         def get_pkg_from_store(id_, type_):
             package = None
             # Attempt to get the package from the package store
@@ -345,27 +340,38 @@ class ExportRpcHandler(mano_dts.AbstractRpcHandler):
 
             return package
 
-        pkg = tosca.ExportTosca()
-
-        # Add NSD and related descriptors for exporting
-        nsd_id = pkg.add_nsd(desc_msg, get_pkg_from_store(desc_id, "nsd"))
-
-        catalog = self.catalog_map["vnfd"]
-        for const_vnfd in desc_msg.constituent_vnfd:
-            vnfd_id = const_vnfd.vnfd_id_ref
-            if vnfd_id in catalog:
-                pkg.add_vnfd(nsd_id,
-                             catalog[vnfd_id],
-                             get_pkg_from_store(vnfd_id, "vnfd"))
-            else:
-                raise tornado.web.HTTPError(
-                    400,
-                    "Unknown VNFD descriptor {} for NSD {}".
-                    format(vnfd_id, nsd_id))
-
-        # Create the archive.
-        pkg.create_archive(transaction_id,
-                           dest=self.application.export_dir)
+        if desc_type == "nsd":
+            pkg = tosca.ExportTosca()
+
+            # Add NSD and related descriptors for exporting
+            nsd_id = pkg.add_nsd(desc_msg, get_pkg_from_store(desc_id, "nsd"))
+
+            catalog = self.catalog_map["vnfd"]
+            for const_vnfd in desc_msg.constituent_vnfd:
+                vnfd_id = const_vnfd.vnfd_id_ref
+                if vnfd_id in catalog:
+                    pkg.add_vnfd(nsd_id,
+                                 catalog[vnfd_id],
+                                 get_pkg_from_store(vnfd_id, "vnfd"))
+                else:
+                    raise tornado.web.HTTPError(
+                        400,
+                        "Unknown VNFD descriptor {} for NSD {}".
+                        format(vnfd_id, nsd_id))
+
+            # Create the archive.
+            pkg.create_archive(transaction_id,
+                               dest=self.application.export_dir)
+        if desc_type == "vnfd":
+            pkg = tosca.ExportTosca()
+            vnfd_id = desc_msg.id
+            pkg.add_single_vnfd(vnfd_id,
+                                 desc_msg,
+                                 get_pkg_from_store(vnfd_id, "vnfd"))
+
+            # Create the archive.
+            pkg.create_archive(transaction_id,
+                               dest=self.application.export_dir)
 
 
 class ExportStateHandler(state.StateHandler):
index 8ccc899..d61e47e 100644 (file)
@@ -61,6 +61,7 @@ class ExportTosca(object):
             self.log = log
         self.nsds = {}
         self.csars = list()
+        self.vnfds = {}
 
     def add_image(self, nsd_id, image, chksum=None):
         if image.name not in self.images:
@@ -73,6 +74,14 @@ class ExportTosca(object):
         if pkg:
             self.nsds[nsd_id]['pkgs'].append(pkg)
 
+    def add_single_vnfd(self, vnfd_id, vnfd, pkg=None):
+        if vnfd is not None:
+            self.vnfds['vnfds'] = []
+            self.vnfds['pkgs'] = []
+        self.vnfds['vnfds'].append(vnfd)
+        if pkg:
+            self.vnfds['pkgs'].append(pkg)
+
     def add_vnfd(self, nsd_id, vnfd, pkg=None):
         if not 'vnfds' in self.nsds[nsd_id]:
             self.nsds[nsd_id]['vnfds'] = []
@@ -112,8 +121,25 @@ class ExportTosca(object):
                                                   archive=True))
         self.log.debug("Created CSAR archive {}".format(self.csars[-1]))
 
+    def create_vnfd_csar(self, dest=None):
+        if dest is None:
+            dest = tempfile.mkdtemp()
+        yangs = {}
+        yangs['vnfd'] = []
+        for vnfd in self.vnfds['vnfds']:
+            yangs['vnfd'].append(vnfd.as_dict())
+        translator = YangTranslator(self.log,
+                                    yangs=yangs,
+                                    packages=self.vnfds['pkgs'])
+        output = translator.translate()
+        self.csars.extend(translator.write_output(output,
+                                                  output_dir=dest,
+                                                  archive=True))
+        self.log.debug("Created CSAR archive {}".format(self.csars[-1]))
+
+
     def create_archive(self, archive_name, dest=None):
-        if not len(self.nsds):
+        if not len(self.nsds) and len(self.vnfds) == 0:
             self.log.error("Did not find any NSDs to export")
             return
 
@@ -127,13 +153,16 @@ class ExportTosca(object):
 
         try:
             # Convert each NSD to a TOSCA template
-            for nsd_id in self.nsds:
-                # Not passing the dest dir to prevent clash in case
-                # multiple export of the same desc happens
-                self.create_csar(nsd_id)
+            if len(self.nsds) > 0:
+                for nsd_id in self.nsds:
+                    # Not passing the dest dir to prevent clash in case
+                    # multiple export of the same desc happens
+                    self.create_csar(nsd_id)
+            elif len(self.vnfds) > 0:
+                self.create_vnfd_csar()
 
         except Exception as e:
-            msg = "Exception converting NSD {}: {}".format(nsd_id, e)
+            msg = "Exception converting NSD/VNFD {}".format(e)
             self.log.exception(e)
             raise YangTranslateNsdError(msg)