Venafi / VenafiPS

Powershell module to fully automate your Venafi TLS Protect Datacenter and Cloud platforms!
https://venafips.readthedocs.io/
Apache License 2.0
18 stars 7 forks source link

Get-TppAttribute fails when looking for attribute 'Certificate' when custom field with same name exists #192

Closed bmw5000 closed 1 year ago

bmw5000 commented 1 year ago

Environment

Operating System: Windows Server 2019
VenafiPS version: 5.4.1
PowerShell version:  5.1.17763.3770 
TPP version (if applicable): 22.3

Steps to reproduce

Create a custom field with a name of "Certificate". Create a device and Basic application. Associate a certificate to the application.

Run Get-TppAttribute -Path "\VED\Policy\Testing\Device\App" -Attribute "Certificate" -VenafiSession $mysession

Expected behavior

Retrieves Certificate attribute from object

Actual behavior

This code block Looks for custom fields with Label matching $thisAttribute.
It then replaces the AttributeName in $params.Body with the guid of the custom field

Desired behavior.

Add a switch that disables the overwrite of the supplied attribute with the custom field guid. or Add a switch to search custom field labels for the supplied attribute

Example 1

[CmdletBinding(DefaultParameterSetName = 'Attribute')]
    param (
        [Parameter(Mandatory, ParameterSetName = 'Attribute', ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'All', ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('DN')]
        [String] $Path,

        [Parameter(Mandatory, ParameterSetName = 'Attribute')]
        [ValidateNotNullOrEmpty()]
        [String[]] $Attribute,

        [ValidateNotNullOrEmpty()]
        [Alias('ClassName', 'PolicyClass')]
        [string] $Class,

        [Parameter(Mandatory, ParameterSetName = 'All')]
        [switch] $All,

        [Parameter()]
        [psobject] $VenafiSession = $script:VenafiSession,

        [Parameter()]
        [switch] $IgnoreCustomFieldLabels
    )

<....>

          if ( $customField -and -not $IgnoreCustomFieldLabels) {
              $params.Body.AttributeName = $customField.Guid
          } else {
              $params.Body.AttributeName = $thisAttribute
          }

image

Example 2

[CmdletBinding(DefaultParameterSetName = 'Attribute')]
    param (
        [Parameter(Mandatory, ParameterSetName = 'Attribute', ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'All', ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('DN')]
        [String] $Path,

        [Parameter(Mandatory, ParameterSetName = 'Attribute')]
        [ValidateNotNullOrEmpty()]
        [String[]] $Attribute,

        [ValidateNotNullOrEmpty()]
        [Alias('ClassName', 'PolicyClass')]
        [string] $Class,

        [Parameter(Mandatory, ParameterSetName = 'All')]
        [switch] $All,

        [Parameter()]
        [psobject] $VenafiSession = $script:VenafiSession,

        [Parameter()]
        [switch] $SearchCustomFieldLabels
    )

<....>

          if ( $customField -and  $SearchCustomFieldLabels) {
              $params.Body.AttributeName = $customField.Guid
          } else {
              $params.Body.AttributeName = $thisAttribute
          }

image

Screenshots

Custom Field image

Device image

App image

Attribute exists on object image

Error image

gdbarron commented 1 year ago

Hi @bmw5000, thanks for reporting. My preferred approach would be to have 2 string array parameters, 1 for attributes and 1 for custom fields. Having a switch allows us to only search on one or the other at 1 time. Any concerns with that approach?

Out of curiosity, why do you need a custom field named 'certificate'?

bmw5000 commented 1 year ago

@gdbarron ,
I don't have any preference on how it gets implemented, as long as it results in being able to retrieve the attribute using VenafiPS.

Question: Why do the custom field query in the function at all. The customfields are available in the $VenafiSession variable. if you want to query custom fields, you can run that section of code in the calling application/script and pass the guid into Get-TppAttribute. This would give you the exact return for the attribute/guid provided.

As for the custom field name 'certificate', it is used in an adaptable app/ca combination to pass a certificate vault between the stages. In hindsight we would not name it the same, but currently it is used in code.

Thanks, Brandon

gdbarron commented 1 year ago

This is implemented for ease of use and so folks don't need to do the lookup and other coding involved, just make the call. Any change we make will be breaking so this might need to wait until the next major release or we simply document a duplicate name as a limitation. Will give it some thought.