.. versionadded:: 2019.2.0

    Create or update a VM extension object "inside" of a VM object.

    required kwargs:
      .. code-block:: yaml

        extension_name: myvmextension
        virtual_machine_name: myvm
        settings: {"commandToExecute": "hostname"}

    optional kwargs:
      .. code-block:: yaml

        resource_group: < inferred from cloud configs >
        location: < inferred from cloud configs >
        publisher: < default: Microsoft.Azure.Extensions >
        virtual_machine_extension_type: < default: CustomScript >
        type_handler_version: < default: 2.0 >
        auto_upgrade_minor_version: < default: True >
        protected_settings: < default: None >

def create_or_update_vmextension(call=None, kwargs=None):  # pylint: disable=unused-argument
    '''
    .. versionadded:: 2019.2.0

    Create or update a VM extension object "inside" of a VM object.

    required kwargs:
      .. code-block:: yaml

        extension_name: myvmextension
        virtual_machine_name: myvm
        settings: {"commandToExecute": "hostname"}

    optional kwargs:
      .. code-block:: yaml

        resource_group: < inferred from cloud configs >
        location: < inferred from cloud configs >
        publisher: < default: Microsoft.Azure.Extensions >
        virtual_machine_extension_type: < default: CustomScript >
        type_handler_version: < default: 2.0 >
        auto_upgrade_minor_version: < default: True >
        protected_settings: < default: None >
    '''
    if kwargs is None:
        kwargs = {}

    if 'extension_name' not in kwargs:
        raise SaltCloudSystemExit(
            'An extension name must be specified'
        )

    if 'virtual_machine_name' not in kwargs:
        raise SaltCloudSystemExit(
            'A virtual machine name must be specified'
        )

    compconn = get_conn(client_type='compute')

    # pylint: disable=invalid-name
    VirtualMachineExtension = getattr(
        compute_models, 'VirtualMachineExtension'
    )

    resource_group = kwargs.get('resource_group') or config.get_cloud_config_value(
                         'resource_group',
                         get_configured_provider(), __opts__, search_global=False
                     )

    if not resource_group:
        raise SaltCloudSystemExit(
            'A resource group must be specified'
        )

    location = kwargs.get('location') or get_location()

    if not location:
        raise SaltCloudSystemExit(
            'A location must be specified'
        )

    publisher = kwargs.get('publisher', 'Microsoft.Azure.Extensions')
    virtual_machine_extension_type = kwargs.get('virtual_machine_extension_type', 'CustomScript')
    type_handler_version = kwargs.get('type_handler_version', '2.0')
    auto_upgrade_minor_version = kwargs.get('auto_upgrade_minor_version', True)
    settings = kwargs.get('settings', {})
    protected_settings = kwargs.get('protected_settings')

    if not isinstance(settings, dict):
        raise SaltCloudSystemExit(
            'VM extension settings are not valid'
        )
    elif 'commandToExecute' not in settings and 'script' not in settings:
        raise SaltCloudSystemExit(
            'VM extension settings are not valid. Either commandToExecute or script must be specified.'
        )

    log.info('Creating VM extension %s', kwargs['extension_name'])

    ret = {}
    try:
        params = VirtualMachineExtension(
            location=location,
            publisher=publisher,
            virtual_machine_extension_type=virtual_machine_extension_type,
            type_handler_version=type_handler_version,
            auto_upgrade_minor_version=auto_upgrade_minor_version,
            settings=settings,
            protected_settings=protected_settings
        )
        poller = compconn.virtual_machine_extensions.create_or_update(
            resource_group,
            kwargs['virtual_machine_name'],
            kwargs['extension_name'],
            params
        )
        ret = poller.result()
        ret = ret.as_dict()

    except CloudError as exc:
        __utils__['azurearm.log_cloud_error']('compute', 'Error attempting to create the VM extension: {0}'.format(exc.message))
        ret = {'error': exc.message}

    return ret