From d2da59065dd11cbfb6845040697e21e4def35b8f Mon Sep 17 00:00:00 2001
From: Juan Antonio Osorio Robles <jaosorior@redhat.com>
Date: Thu, 15 Dec 2016 14:28:57 +0200
Subject: [PATCH] Add hook to generate metadata from service profiles

This enables the deployer to dynamically add nova metadata to the
servers based on the output of service profiles that implement the
metadata_settings key in the role_data output for the profiles.

One can set an implementation via the OS::TripleO::ServerMetadataHook
resource, which currently is set as OS::Heat::None. So, because of
the default implementation, if left untouched it actually does
nothing.

Currently, besides the list, which is metadata_settings, this hook also
takes the name of the node that it's setting the metadata for.

This is useful for nova vendordata plugins that can parse said metadata.

Change-Id: I8a937f711f0b90156fbb6c4632760435ef846474
---
 overcloud-resource-registry-puppet.j2.yaml |  2 ++
 overcloud.j2.yaml                          |  1 +
 puppet/blockstorage-role.yaml              |  4 ++++
 puppet/cephstorage-role.yaml               |  4 ++++
 puppet/compute-role.yaml                   |  4 ++++
 puppet/controller-role.yaml                |  4 ++++
 puppet/objectstorage-role.yaml             |  4 ++++
 puppet/role.role.j2.yaml                   |  4 ++++
 puppet/services/README.rst                 | 14 ++++++++++++++
 puppet/services/services.yaml              |  6 ++++++
 10 files changed, 47 insertions(+)

diff --git a/overcloud-resource-registry-puppet.j2.yaml b/overcloud-resource-registry-puppet.j2.yaml
index ebbeef6eec..da71719cf9 100644
--- a/overcloud-resource-registry-puppet.j2.yaml
+++ b/overcloud-resource-registry-puppet.j2.yaml
@@ -41,6 +41,8 @@ resource_registry:
   # in the jinja loop
   OS::TripleO::Controller::Net::SoftwareConfig: net-config-bridge.yaml
 
+  OS::TripleO::ServiceServerMetadataHook: OS::Heat::None
+
   OS::TripleO::Server: OS::Nova::Server
 
   # This creates the "heat-admin" user for all OS images by default
diff --git a/overcloud.j2.yaml b/overcloud.j2.yaml
index f7e6f37f8c..a765216cbc 100644
--- a/overcloud.j2.yaml
+++ b/overcloud.j2.yaml
@@ -363,6 +363,7 @@ resources:
                     services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
           ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
           MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
+          ServiceMetadataSettings: {get_attr: [{{role.name}}ServiceChain, role_data, service_metadata_settings]}
 {% endfor %}
 
   hostsConfig:
diff --git a/puppet/blockstorage-role.yaml b/puppet/blockstorage-role.yaml
index 7d1f8d8f50..f741447583 100644
--- a/puppet/blockstorage-role.yaml
+++ b/puppet/blockstorage-role.yaml
@@ -102,6 +102,9 @@ parameters:
   MonitoringSubscriptions:
     type: comma_delimited_list
     default: []
+  ServiceMetadataSettings:
+    type: json
+    default: {}
   ConfigCommand:
     type: string
     description: Command which will be run whenever configuration data changes
@@ -137,6 +140,7 @@ resources:
         map_merge:
           - {get_param: ServerMetadata}
           - {get_param: BlockStorageServerMetadata}
+          - {get_param: ServiceMetadataSettings}
       scheduler_hints: {get_param: BlockStorageSchedulerHints}
 
   # Combine the NodeAdminUserData and NodeUserData mime archives
diff --git a/puppet/cephstorage-role.yaml b/puppet/cephstorage-role.yaml
index 2c46bf1a39..05ecb1812d 100644
--- a/puppet/cephstorage-role.yaml
+++ b/puppet/cephstorage-role.yaml
@@ -108,6 +108,9 @@ parameters:
   MonitoringSubscriptions:
     type: comma_delimited_list
     default: []
+  ServiceMetadataSettings:
+    type: json
+    default: {}
   ConfigCommand:
     type: string
     description: Command which will be run whenever configuration data changes
@@ -143,6 +146,7 @@ resources:
         map_merge:
           - {get_param: ServerMetadata}
           - {get_param: CephStorageServerMetadata}
+          - {get_param: ServiceMetadataSettings}
       scheduler_hints: {get_param: CephStorageSchedulerHints}
 
   # Combine the NodeAdminUserData and NodeUserData mime archives
diff --git a/puppet/compute-role.yaml b/puppet/compute-role.yaml
index 0a2598c1cb..bf580221b1 100644
--- a/puppet/compute-role.yaml
+++ b/puppet/compute-role.yaml
@@ -120,6 +120,9 @@ parameters:
   MonitoringSubscriptions:
     type: comma_delimited_list
     default: []
+  ServiceMetadataSettings:
+    type: json
+    default: {}
   ConfigCommand:
     type: string
     description: Command which will be run whenever configuration data changes
@@ -157,6 +160,7 @@ resources:
         map_merge:
           - {get_param: ServerMetadata}
           - {get_param: NovaComputeServerMetadata}
+          - {get_param: ServiceMetadataSettings}
       scheduler_hints: {get_param: NovaComputeSchedulerHints}
 
   # Combine the NodeAdminUserData and NodeUserData mime archives
diff --git a/puppet/controller-role.yaml b/puppet/controller-role.yaml
index 5e03adcd52..221bfed799 100644
--- a/puppet/controller-role.yaml
+++ b/puppet/controller-role.yaml
@@ -134,6 +134,9 @@ parameters:
   MonitoringSubscriptions:
     type: comma_delimited_list
     default: []
+  ServiceMetadataSettings:
+    type: json
+    default: {}
   ConfigCommand:
     type: string
     description: Command which will be run whenever configuration data changes
@@ -176,6 +179,7 @@ resources:
         map_merge:
           - {get_param: ServerMetadata}
           - {get_param: ControllerServerMetadata}
+          - {get_param: ServiceMetadataSettings}
       scheduler_hints: {get_param: ControllerSchedulerHints}
 
   # Combine the NodeAdminUserData and NodeUserData mime archives
diff --git a/puppet/objectstorage-role.yaml b/puppet/objectstorage-role.yaml
index 088a2e3d7a..640378c89c 100644
--- a/puppet/objectstorage-role.yaml
+++ b/puppet/objectstorage-role.yaml
@@ -102,6 +102,9 @@ parameters:
   MonitoringSubscriptions:
     type: comma_delimited_list
     default: []
+  ServiceMetadataSettings:
+    type: json
+    default: {}
   ConfigCommand:
     type: string
     description: Command which will be run whenever configuration data changes
@@ -137,6 +140,7 @@ resources:
         map_merge:
           - {get_param: ServerMetadata}
           - {get_param: SwiftStorageServerMetadata}
+          - {get_param: ServiceMetadataSettings}
       scheduler_hints: {get_param: ObjectStorageSchedulerHints}
 
   # Combine the NodeAdminUserData and NodeUserData mime archives
diff --git a/puppet/role.role.j2.yaml b/puppet/role.role.j2.yaml
index acb7677ae1..7b3d2d3107 100644
--- a/puppet/role.role.j2.yaml
+++ b/puppet/role.role.j2.yaml
@@ -118,6 +118,9 @@ parameters:
   MonitoringSubscriptions:
     type: comma_delimited_list
     default: []
+  ServiceMetadataSettings:
+    type: json
+    default: {}
   ConfigCommand:
     type: string
     description: Command which will be run whenever configuration data changes
@@ -160,6 +163,7 @@ resources:
         map_merge:
           - {get_param: ServerMetadata}
           - {get_param: {{role}}ServerMetadata}
+          - {get_param: ServiceMetadataSettings}
       scheduler_hints: {get_param: {{role}}SchedulerHints}
 
   # Combine the NodeAdminUserData and NodeUserData mime archives
diff --git a/puppet/services/README.rst b/puppet/services/README.rst
index 856b306e50..6e4e9c1d66 100644
--- a/puppet/services/README.rst
+++ b/puppet/services/README.rst
@@ -74,3 +74,17 @@ step, "step2" for the second, etc.
    6) Start control-plane services
 
    7) Any additional online migration tasks (e.g data migrations)
+
+Nova Server Metadata Settings
+-----------------------------
+
+One can use the hook of type `OS::TripleO::ServiceServerMetadataHook` to pass
+entries to the nova instances' metadata. It is, however, disabled by default.
+In order to overwrite it one needs to define it in the resource registry. An
+implementation of this hook needs to conform to the following:
+
+* It needs to define an input called `RoleData` of json type. This gets as
+  input the contents of the `role_data` for each role's ServiceChain.
+
+* This needs to define an output called `metadata` which will be given to the
+  Nova Server resource as the instance's metadata.
diff --git a/puppet/services/services.yaml b/puppet/services/services.yaml
index 13df5bbe9e..97f8706182 100644
--- a/puppet/services/services.yaml
+++ b/puppet/services/services.yaml
@@ -42,6 +42,11 @@ resources:
   LoggingConfiguration:
     type: OS::TripleO::LoggingConfiguration
 
+  ServiceServerMetadataHook:
+    type: OS::TripleO::ServiceServerMetadataHook
+    properties:
+      RoleData: {get_attr: [ServiceChain, role_data]}
+
 outputs:
   role_data:
     description: Combined Role data for this set of services.
@@ -113,3 +118,4 @@ outputs:
           # Note we use distinct() here to filter any identical tasks, e.g yum update for all services
           expression: $.data.where($ != null).select($.get('upgrade_tasks')).where($ != null).flatten().distinct()
           data: {get_attr: [ServiceChain, role_data]}
+      service_metadata_settings: {get_attr: [ServiceServerMetadataHook, metadata]}