Repository: Azure/azure-linux-extensions

Issue:
Need a better error message if LAD config is invalid
I'm getting a weird error when trying to deploy the Diagnostics extension via an ARM template:

```json
Deployment failed. Correlation ID: b38c8bef-1aef-49fc-b57d-55dfb8490811. {
  "status": "Failed",
  "error": {
    "code": "ResourceDeploymentFailure",
    "message": "The resource operation completed with terminal provisioning state 'Failed'.",
    "details": [
      {
        "code": "VMExtensionProvisioningError",
        "message": "VM has reported a failure when processing extension 'Microsoft.Azure.Diagnostics'. Error message: \"Extension operation Daemon failed:unsupported operand type(s) for +: 'NoneType' and 'str'\"."
      }
    ]
  }
}
```

Looking at the logs, this happens when the extension tries to initialise the location of the certificates:

```
2017/12/01 19:22:06 [Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109] Disable verbose log
2017/12/01 19:22:06 [Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109] Dispatching command:-daemon
2017/12/01 19:22:06 [Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109] Deployment ID found: 3c6795e8-f196-4341-964e-4f5ef3d81b3a.
2017/12/01 19:22:06 ERROR:[Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109] Failed to perform extension operation Daemon with error:unsupported operand type(s) for +: 'NoneType' and 'str', Traceback (most recent call last):
2017/12/01 19:22:06 ERROR:  File "/var/lib/waagent/Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109/diagnostic.py", line 296, in main
2017/12/01 19:22:06 ERROR:    configurator = create_core_components_configs()
2017/12/01 19:22:06 ERROR:  File "/var/lib/waagent/Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109/diagnostic.py", line 192, in create_core_components_configs
2017/12/01 19:22:06 ERROR:    read_uuid, encrypt_string, hutil.log, hutil.error)
2017/12/01 19:22:06 ERROR:  File "/var/lib/waagent/Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109/lad_config_all.py", line 97, in __init__
2017/12/01 19:22:06 ERROR:    self._cert_path = os.path.join(waagent_dir, thumbprint + '.crt')
2017/12/01 19:22:06 ERROR:TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
2017/12/01 19:22:06 ERROR:
2017/12/01 19:22:06 [Microsoft.Azure.Diagnostics.LinuxDiagnostic-3.0.109] Daemon,error,0,Extension operation Daemon failed:unsupported operand type(s) for +: 'NoneType' and 'str'
```

For some reason, the thumbprint is set to `None`, even though I can see `.crt` and `.prv` files in `/var/lib/waagent`.

Is there a working example of how to deploy the extension via an ARM template? So far I'm using this:

`(inside VM definition)`
```json
"resources": [
        {
          "type": "Microsoft.Compute/virtualMachines/extensions",
          "name": "[concat(variables('jumpBoxName'), '/Microsoft.Azure.Diagnostics')]",
          "apiVersion": "2017-03-30",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[concat('Microsoft.Compute/virtualMachines/',variables('jumpBoxName'))]",
            "[concat('Microsoft.Storage/storageAccounts/',variables('diagsName'))]"            
          ],
          "properties": {
            "publisher": "Microsoft.Azure.Diagnostics",
            "type": "LinuxDiagnostic",
            "typeHandlerVersion": "3.0",
            "autoUpgradeMinorVersion": true,
            "settings": {
              "storageAccount": "[variables('diagsName')]"
              "ladCfg": <lots of metrics settings>
            }
          }
        },
```


Discussion:
Your configuration is missing the "protectedSettings" JSON object within the "properties" for the extension. The protectedSettings are mandatory; among other things, that's where you pass the necessary credentials to the extension. See [this section](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/diagnostic-extension#protected-settings) of the LAD 3.0 documentation.

LAD really should issue a much clearer error message for this case. Thanks for the bug report.
Thanks! I’m clear on the reasons now. I’m also OK with closing this in favor of a more explicit issue pertaining to the error message if you think that’s best.
Nah, leave this one open; it's already marked as a bug, the right dev will get to it. :-)
Hello,
I'm new with ARM Template deployment and i want to enable diagnostics extention on some VMs.
Could you please give me a demo or a link that i can follow to do it ?
Best Regards,

is this issue got fixed ?  i'm still getting Linux Diagnostic extension failure . 
 Code="VMExtensionProvisioningError" Message="VM has reported a failure when processing extension 'LinuxDiagnostic'. Error message: \"Extension operation Enable failed:unsupported operand type(s) for +: 'NoneType' and 'str'\"\r\n\r\nMore information on troubleshooting is available at https://aka.ms/VMExtensionLinuxDiagnosticsTroubleshoot "
I have a similar problem trying to deploy this extension using ARM. I cannot see what I do wrong from the error message:
`
{
    "status": "Failed",
    "error": {
        "code": "ResourceDeploymentFailure",
        "message": "The resource operation completed with terminal provisioning state 'Failed'.",
        "details": [
            {
                "code": "VMExtensionProvisioningError",
                "message": "VM has reported a failure when processing extension 'LinuxDiagnostic'. Error message: \"Extension operation Enable failed:'NoneType' object has no attribute 'get_fluentd_syslog_src_config'\"\r\n\r\nMore information on troubleshooting is available at https://aka.ms/VMExtensionLinuxDiagnosticsTroubleshoot "
            }
        ]
    }
}
`

The template has the following resource in it:

`
{
    "comments": "~~ VM Extension - LinuxDiagnostic  ~~",
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "apiVersion": "2018-10-01",
    "name": "[concat(variables('vmNamePrefix'), padLeft(copyindex('extDiagLinuxLoop', 1), 2, '0'), '/LinuxDiagnostic')]",
    "condition": "[not(variables('isWindowsOS'))]",
    "tags": "[variables('tagResources')]",
    "copy": {
        "name": "extDiagLinuxLoop",
        "count": "[parameters('numberOfInstances')]"
    },
    "location": "[variables('rgLocation')]",
    "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmNamePrefix'), padLeft(copyindex('extDiagLinuxLoop', 1), 2, '0')))]",
        "[resourceId('Microsoft.Compute/virtualMachines/extensions', concat(variables('vmNamePrefix'), padLeft(copyindex('extDiagLinuxLoop', 1), 2, '0')), 'MicrosoftMonitoringAgent')]"
    ],
    "properties": {
        "publisher": "Microsoft.Azure.Diagnostics",
        "type": "LinuxDiagnostic",
        "typeHandlerVersion": "3.0",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "ladCfg": {
                "diagnosticMonitorConfiguration": {
                    "syslogEvents": {
                        "syslogEventConfiguration": {
                            "LOG_AUTH": "LOG_DEBUG",
                            "LOG_AUTHPRIV": "LOG_DEBUG",
                            "LOG_CRON": "LOG_DEBUG",
                            "LOG_DAEMON": "LOG_DEBUG",
                            "LOG_FTP": "LOG_DEBUG",
                            "LOG_KERN": "LOG_DEBUG",
                            "LOG_LOCAL0": "LOG_DEBUG",
                            "LOG_LOCAL1": "LOG_DEBUG",
                            "LOG_LOCAL2": "LOG_DEBUG",
                            "LOG_LOCAL3": "LOG_DEBUG",
                            "LOG_LOCAL4": "LOG_DEBUG",
                            "LOG_LOCAL5": "LOG_DEBUG",
                            "LOG_LOCAL6": "LOG_DEBUG",
                            "LOG_LOCAL7": "LOG_DEBUG",
                            "LOG_LPR": "LOG_DEBUG",
                            "LOG_MAIL": "LOG_DEBUG",
                            "LOG_NEWS": "LOG_DEBUG",
                            "LOG_SYSLOG": "LOG_DEBUG",
                            "LOG_USER": "LOG_DEBUG",
                            "LOG_UUCP": "LOG_DEBUG"
                        }
                    },
                    "sampleRateInSeconds": 15,
                    "eventVolume": "Medium",
                    "metrics": {
                        "resourceId": "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmNamePrefix'), padLeft(copyindex('extDiagLinuxLoop', 1), 2, '0')))]",
                        "metricAggregation": [
                            {
                                "scheduledTransferPeriod": "PT1H"
                            },
                            {
                                "scheduledTransferPeriod": "PT1M"
                            }
                        ]
                    },
                    "performanceCounters": {
                        "performanceCounterConfiguration": [
                            {
                                "annotation": [
                                    {
                                        "displayName": "Filesystem % free space",
                                        "locale": "en-us"
                                    }
                                ],
                                "class": "filesystem",
                                "condition": "IsAggregate=TRUE",
                                "counter": "percentfreespace",
                                "counterSpecifier": "/builtin/filesystem/percentfreespace",
                                "type": "builtin",
                                "unit": "Percent"
                            },
                            {
                                "annotation": [
                                    {
                                        "displayName": "Filesystem % used space",
                                        "locale": "en-us"
                                    }
                                ],
                                "class": "filesystem",
                                "condition": "IsAggregate=TRUE",
                                "counter": "percentusedspace",
                                "counterSpecifier": "/builtin/filesystem/percentusedspace",
                                "type": "builtin",
                                "unit": "Percent"
                            },
                            {
                                "annotation": [
                                    {
                                        "displayName": "Filesystem used space",
                                        "locale": "en-us"
                                    }
                                ],
                                "class": "filesystem",
                                "condition": "IsAggregate=TRUE",
                                "counter": "usedspace",
                                "counterSpecifier": "/builtin/filesystem/usedspace",
                                "type": "builtin",
                                "unit": "Bytes"
                            },
                            {
                                "annotation": [
                                    {
                                        "displayName": "Filesystem read bytes/sec",
                                        "locale": "en-us"
                                    }
                                ],
                                "class": "filesystem",
                                "condition": "IsAggregate=TRUE",
                                "counter": "bytesreadpersecond",
                                "counterSpecifier": "/builtin/filesystem/bytesreadpersecond",
                                "type": "builtin",
                                "unit": "CountPerSecond"
                            },
                            {
                                "annotation": [
                                    {
                                        "displayName": "Filesystem free space",
                                        "locale": "en-us"
                                    }
                                ],
                                "class": "filesystem",
                                "condition": "IsAggregate=TRUE",
                                "counter": "freespace",
                                "counterSpecifier": "/builtin/filesystem/freespace",
                                "type": "builtin",
                                "unit": "Bytes"
                            },
                            {
                                "annotation": [
                                    {
                                        "displayName": "Filesystem % free inodes",
                                        "locale": "en-us"
                                    }
                                ],
                                "class": "filesystem",
                                "condition": "IsAggregate=TRUE",
                                "counter": "percentfreeinodes",
                                "counterSpecifier": "/builtin/filesystem/percentfreeinodes",
                                "type": "builtin",
                                "unit": "Percent"
                            }
                        ]
                    }
                }
            },
            "StorageAccount": "[variables('vmDiagStorageAccountName')]"
        },
        "protectedSettings": {
            "storageAccountName": "[variables('vmDiagStorageAccountName')]",
            "storageAccountSasToken": "[listAccountSas(variables('vmDiagStorageAccountName'), '2019-06-01', variables('accountSasProperties'))]",
            "storageAccountEndPoint": "https://core.windows.net/"
        }
    }
}
`
Getting the same issue, any updates?

Resolving patch:
diff --git a/Diagnostic/lad_config_all.py b/Diagnostic/lad_config_all.py
--- a/Diagnostic/lad_config_all.py
+++ b/Diagnostic/lad_config_all.py
@@ -93,7 +93,22 @@ def __init__(self, ext_settings, ext_dir, waagent_dir, deployment_id,
         # If we decide to also read sinksConfig from ladCfg, do it first, so that private settings override
 
         # Get encryption settings
-        thumbprint = ext_settings.get_handler_settings()['protectedSettingsCertThumbprint']
+        handlerSettings = ext_settings.get_handler_settings()
+
+        if handlerSettings['protectedSettings'] is None:
+            errorMsg = "Settings did not contain protectedSettings. For information on protected settings, " \
+                          "visit https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/diagnostics-linux#protected-settings."
+            self._logger_error(errorMsg)
+            raise LadLoggingConfigException(errorMsg)
+
+        if handlerSettings['protectedSettingsCertThumbprint'] is None:
+            errorMsg = "Settings did not contain protectedSettingsCertThumbprint. For information on protected settings, " \
+                          "visit https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/diagnostics-linux#protected-settings."
+            self._logger_error(errorMsg)
+            raise LadLoggingConfigException(errorMsg)
+
+        thumbprint = handlerSettings['protectedSettingsCertThumbprint']
+
         self._cert_path = os.path.join(waagent_dir, thumbprint + '.crt')
         self._pkey_path = os.path.join(waagent_dir, thumbprint + '.prv')
 


Test patch: