AtlassianPS / JiraPS

PowerShell module to interact with Atlassian JIRA
https://AtlassianPS.org/module/JiraPS
MIT License
321 stars 131 forks source link

New-JiraIssue - Service Desk Get-Member issue #118

Closed JoeJe1993 closed 6 years ago

JoeJe1993 commented 7 years ago

When using New-JiraIssue on a Service Desk, an error about an incomplete Get-Member cmdlet comes up in ConvertTo-JiraCreateMetaField.ps1.

This doesn't happen on other types of Jira boards

image

image

JoeJe1993 commented 7 years ago

Debug info:

image

lipkau commented 7 years ago

Hi. Can you please run the command with -debug? I expect for you to get this debug message:

"[New-JiraIssue] Encountered an error reading configuration data."

If you do, it would be great if you can enter debug mode (suspend) and print $err | FL * -force And show us the result.

It is important to run that command in the debug mode, the variable $err will be deleted once the function exits

JoeJe1993 commented 7 years ago

Just attached a screenshot with all the debug info for you.

lipkau commented 7 years ago

It appears that the input object of issueCreateMeta is different that the ones we know. Probably a service desk thing.

@all : can anyone​ confirm this?

I will try to reproduce after I get back from my vacation

lipkau commented 7 years ago

Does Get-JiraIssueCreateMetadata return an error too? If not, please attach the output of Export-Clixml

JoeJe1993 commented 7 years ago

It returns an error.

image

JoeJe1993 commented 7 years ago

Hi @lipkau, is what I've provided okay?

lipkau commented 7 years ago

No. I need the PSObject that is passed on to ConvertTo-JiraCreateMetaField

lipkau commented 7 years ago

I will be able to send you a snippet to get me the info I need tomorrow

lipkau commented 7 years ago

@JoeJe1993 : after loading the module, please load this into your powershell session:

function Get-JiraIssueCreateMetadata
{
    <#
    .Synopsis
       Returns metadata required to create an issue in JIRA
    .DESCRIPTION
       This function returns metadata required to create an issue in JIRA - the fields that can be defined in the process of creating an issue.  This can be used to identify custom fields in order to pass them to New-JiraIssue.

       This function is particularly useful when your JIRA instance includes custom fields that are marked as mandatory.  The required fields can be identified from this See the examples for more details on this approach.
    .EXAMPLE
       Get-JiraIssueCreateMetadata -Project 'TEST' -IssueType 'Bug'
       This example returns the fields available when creating an issue of type Bug under project TEST.
    .EXAMPLE
       Get-JiraIssueCreateMetadata -Project 'JIRA' -IssueType 'Bug' | ? {$_.Required -eq $true}
       This example returns fields available when creating an issue of type Bug under the project Jira.  It then uses Where-Object (aliased by the question mark) to filter only the fields that are required.
    .INPUTS
       This function does not accept pipeline input.
    .OUTPUTS
       This function outputs the PSJira.Field objects that represent JIRA's create metadata.
    .NOTES
       This function requires either the -Credential parameter to be passed or a persistent JIRA session. See New-JiraSession for more details.  If neither are supplied, this function will run with anonymous access to JIRA.
    #>
    [CmdletBinding()]
    param(
        # Project ID or key
        [Parameter(Mandatory = $true,
                   Position = 0)]
        [String] $Project,

        # Issue type ID or name
        [Parameter(Mandatory = $true,
                   Position = 1)]
        [String] $IssueType,

        [String] $ConfigFile,

        # Credentials to use to connect to Jira
        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential] $Credential
    )

    begin
    {
        Write-Debug "[Get-JiraIssueCreateMetadata] Reading server from config file"
        try
        {
            $server = Get-JiraConfigServer -ConfigFile $ConfigFile -ErrorAction Stop
        } catch {
            $err = $_
            Write-Debug "[Get-JiraIssueCreateMetadata] Encountered an error reading the Jira server."
            throw $err
        }

        Write-Debug "[Get-JiraIssueCreateMetadata] Building URI for REST call based on parameters"
        $uri = "$server/rest/api/latest/issue/createmeta?"

        Write-Debug "[Get-JiraIssueCreateMetadata] Obtaining project ID for project [$Project]"
        $projectObj = Get-JiraProject -Project $Project -Credential $Credential
        if ($projectObj)
        {
            $projectId = $projectObj.Id
            $uri = "${uri}projectIds=$projectId&"
        } else {
            throw "No project was found for the given Project [$Project]. Use Get-JiraProject for more information on this issue."
        }

        Write-Debug "[Get-JiraIssueCreateMetadata] Obtaining issue type ID for issue type [$IssueType]"
        $issueTypeObj = Get-JiraIssueType -IssueType $IssueType -Credential $Credential
        if ($issueTypeObj)
        {
            $issueTypeId = $issueTypeObj.Id
            $uri = "${uri}issuetypeIds=$issueTypeId&"
        } else {
            throw "No issue types were found for the given IssueType [$IssueType]. Use Get-JiraIssueType for more information on this issue."
        }

        $uri = "${uri}expand=projects.issuetypes.fields"
    }

    process
    {
        Write-Debug "[Get-JiraIssueCreateMetadata] Preparing for blastoff!"
        $jiraResult = Invoke-JiraMethod -Method Get -URI $uri -Credential $Credential

        if ($jiraResult)
        {
            if (@($jiraResult.projects).Count -eq 0)
            {
                Write-Debug "[Get-JiraIssueCreateMetadata] No project results were found. Throwing exception."
                throw "No projects were found for the given project [$Project]. Use Get-JiraProject for more details."
            } elseif (@($jiraResult.projects).Count -gt 1) {
                Write-Debug "[Get-JiraIssueCreateMetadata] Multiple project results were found. Throwing exception."
                throw "Multiple projects were found for the given project [$Project]. Refine the parameters to return only one project."
            }

            $projectId = $jiraResult.projects.id
            $projectKey = $jiraResult.projects.key

            Write-Debug "[Get-JiraIssueCreateMetadata] Identified project key: [$Project]"

            if (@($jiraResult.projects.issuetypes) -eq 0)
            {
                Write-Debug "[Get-JiraIssueCreateMetadata] No issue type results were found. Throwing exception."
                throw "No issue types were found for the given issue type [$IssueType]. Use Get-JiraIssueType for more details."
            } elseif (@($jiraResult.projects.issuetypes).Count -gt 1) {
                Write-Debug "[Get-JiraIssueCreateMetadata] Multiple issue type results were found. Throwing exception."
                throw "Multiple issue types were found for the given issue type [$IssueType]. Refine the parameters to return only one issue type."
            }

            Write-Debug "[Get-JiraIssueCreateMetadata] Converting results to custom object"
            $global:DEBUG_metadata = $jiraResult
            $obj = ConvertTo-JiraCreateMetaField -InputObject $jiraResult

            Write-Debug "Outputting results"
            Write-Output $obj

#            Write-Output $jiraResult
        } else {
            Write-Debug "[Get-JiraIssueCreateMetadata] No results were returned from JIRA."
        }
    }
}

after this, please run this command:

Get-JiraIssueCreateMetadata -Project DOC -IssueType Task

and then give me the output of this command:

$DEBUG_metadata | convertto-json -Depth 99
JoeJe1993 commented 7 years ago

With your new Get-JiraIssueCreateMetadata

image

JoeJe1993 commented 7 years ago

Just a quick note, I'm sure you're already aware of this, but this is the environment we're trying to open tickets on.

image

lipkau commented 7 years ago

@JoeJe1993, this function I provided doesn't fix anything. It only allow you the give me this information is need with these two commands:

after this, please run this command:

Get-JiraIssueCreateMetadata -Project DOC -IssueType Task

and then give me the output of this command:

$DEBUG_metadata | convertto-json -Depth 99
JoeJe1993 commented 7 years ago

Hi @lipkau, apologies, here's the output you wanted.

image

lipkau commented 7 years ago

that doesn't look right. can you paste the command you ran?

JoeJe1993 commented 7 years ago
Import-Module PSJira

Set-JiraConfigServer -Server 'https://[DOMAIN]:443/jira'

function Get-JiraIssueCreateMetadata
{
    <#
    .Synopsis
       Returns metadata required to create an issue in JIRA
    .DESCRIPTION
       This function returns metadata required to create an issue in JIRA - the fields that can be defined in the process of creating an issue.  This can be used to identify custom fields in order to pass them to New-JiraIssue.

       This function is particularly useful when your JIRA instance includes custom fields that are marked as mandatory.  The required fields can be identified from this See the examples for more details on this approach.
    .EXAMPLE
       Get-JiraIssueCreateMetadata -Project 'TEST' -IssueType 'Bug'
       This example returns the fields available when creating an issue of type Bug under project TEST.
    .EXAMPLE
       Get-JiraIssueCreateMetadata -Project 'JIRA' -IssueType 'Bug' | ? {$_.Required -eq $true}
       This example returns fields available when creating an issue of type Bug under the project Jira.  It then uses Where-Object (aliased by the question mark) to filter only the fields that are required.
    .INPUTS
       This function does not accept pipeline input.
    .OUTPUTS
       This function outputs the PSJira.Field objects that represent JIRA's create metadata.
    .NOTES
       This function requires either the -Credential parameter to be passed or a persistent JIRA session. See New-JiraSession for more details.  If neither are supplied, this function will run with anonymous access to JIRA.
    #>
    [CmdletBinding()]
    param(
        # Project ID or key
        [Parameter(Mandatory = $true,
                   Position = 0)]
        [String] $Project,

        # Issue type ID or name
        [Parameter(Mandatory = $true,
                   Position = 1)]
        [String] $IssueType,

        [String] $ConfigFile,

        # Credentials to use to connect to Jira
        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential] $Credential
    )

    begin
    {
        Write-Debug "[Get-JiraIssueCreateMetadata] Reading server from config file"
        try
        {
            $server = Get-JiraConfigServer -ConfigFile $ConfigFile -ErrorAction Stop
        } catch {
            $err = $_
            Write-Debug "[Get-JiraIssueCreateMetadata] Encountered an error reading the Jira server."
            throw $err
        }

        Write-Debug "[Get-JiraIssueCreateMetadata] Building URI for REST call based on parameters"
        $uri = "$server/rest/api/latest/issue/createmeta?"

        Write-Debug "[Get-JiraIssueCreateMetadata] Obtaining project ID for project [$Project]"
        $projectObj = Get-JiraProject -Project $Project -Credential $Credential
        if ($projectObj)
        {
            $projectId = $projectObj.Id
            $uri = "${uri}projectIds=$projectId&"
        } else {
            throw "No project was found for the given Project [$Project]. Use Get-JiraProject for more information on this issue."
        }

        Write-Debug "[Get-JiraIssueCreateMetadata] Obtaining issue type ID for issue type [$IssueType]"
        $issueTypeObj = Get-JiraIssueType -IssueType $IssueType -Credential $Credential
        if ($issueTypeObj)
        {
            $issueTypeId = $issueTypeObj.Id
            $uri = "${uri}issuetypeIds=$issueTypeId&"
        } else {
            throw "No issue types were found for the given IssueType [$IssueType]. Use Get-JiraIssueType for more information on this issue."
        }

        $uri = "${uri}expand=projects.issuetypes.fields"
    }

    process
    {
        Write-Debug "[Get-JiraIssueCreateMetadata] Preparing for blastoff!"
        $jiraResult = Invoke-JiraMethod -Method Get -URI $uri -Credential $Credential

        if ($jiraResult)
        {
            if (@($jiraResult.projects).Count -eq 0)
            {
                Write-Debug "[Get-JiraIssueCreateMetadata] No project results were found. Throwing exception."
                throw "No projects were found for the given project [$Project]. Use Get-JiraProject for more details."
            } elseif (@($jiraResult.projects).Count -gt 1) {
                Write-Debug "[Get-JiraIssueCreateMetadata] Multiple project results were found. Throwing exception."
                throw "Multiple projects were found for the given project [$Project]. Refine the parameters to return only one project."
            }

            $projectId = $jiraResult.projects.id
            $projectKey = $jiraResult.projects.key

            Write-Debug "[Get-JiraIssueCreateMetadata] Identified project key: [$Project]"

            if (@($jiraResult.projects.issuetypes) -eq 0)
            {
                Write-Debug "[Get-JiraIssueCreateMetadata] No issue type results were found. Throwing exception."
                throw "No issue types were found for the given issue type [$IssueType]. Use Get-JiraIssueType for more details."
            } elseif (@($jiraResult.projects.issuetypes).Count -gt 1) {
                Write-Debug "[Get-JiraIssueCreateMetadata] Multiple issue type results were found. Throwing exception."
                throw "Multiple issue types were found for the given issue type [$IssueType]. Refine the parameters to return only one issue type."
            }

            Write-Debug "[Get-JiraIssueCreateMetadata] Converting results to custom object"
            $global:DEBUG_metadata = $jiraResult
            $obj = ConvertTo-JiraCreateMetaField -InputObject $jiraResult

            Write-Debug "Outputting results"
            Write-Output $obj

#            Write-Output $jiraResult
        } else {
            Write-Debug "[Get-JiraIssueCreateMetadata] No results were returned from JIRA."
        }
    }
}

[net.servicepointmanager]::securityprotocol = [net.securityprotocoltype]::Tls12

$Credentials = New-Object System.Management.Automation.PSCredential((Get-Credential))

Get-JiraIssueCreateMetadata -Project "DOC" -IssueType Task -Credential $Credentials

$DEBUG_metadata|ConvertTo-Json -Depth 99
JoeJe1993 commented 7 years ago

code.txt

lipkau commented 7 years ago

what is the content of $DEBUG_metadata.projects?

lipkau commented 7 years ago

Can you send me c:\temp\dump.xml after running

Export-Clixml -InputObject $DEBUG_metadata -Path c:\temp\dump.xml

?

JoeJe1993 commented 7 years ago

image

JoeJe1993 commented 7 years ago

GitHub doesn't accept XML, so change the file extension to xml once downloaded.

dump.txt

lipkau commented 7 years ago

I wasn't expecting that... It seems to be a limitation of JIRA.

I will investigate further, but it doesn't look too promising

JoeJe1993 commented 7 years ago

Hi @lipkau, Any updates?

JoeJe1993 commented 7 years ago

Bump.

replicaJunction commented 7 years ago

In your provided screenshot, issuetypes is null, which is what's causing the error - see lines 36 and 37 of ConvertTo-JiraCreateMetaField. We need to understand why this particular project (DOC, name was redacted in that screenshot) in your Jira instance isn't returning any issue types, as I've never seen that happen before.

I'm having trouble accessing the Atlassian documentation at the moment, but if you're an admin in your JIRA environment, go to JIRA Administration > Projects, select your DOC project, and hit the "Issue Types" link in the sidebar. If you're not an admin, please ask for this info from your administrator.

You can also get some info using Get-JiraIssueType. See if that list contains all of the items in the project view above.

JoeJe1993 commented 7 years ago

Issue types: image

I'll grab the output of Get-JiraIssueType in the next 5 - 10 mins

JoeJe1993 commented 7 years ago

Here's the output:

image

JoeJe1993 commented 7 years ago

FYI, here's the version of Jira Service Desk we're running

image

lipkau commented 7 years ago

please run this code and give us the output json (please redact the server name in the json)

$myServer = "https://"
$myProject = "DOC"

$cred = (Get-Credential)
[String] $Username = $Cred.UserName
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${Username}:$($Cred.GetNetworkCredential().Password)"))

$headers = @{    'Authorization' = "Basic $token" }

(Invoke-WebRequest -Uri "$myServer/rest/api/2/project/$myProject" -Headers $headers -Method "GET" -UseBasicParsing).Content
JoeJe1993 commented 7 years ago

image

lipkau commented 7 years ago
$myServer = "https://"
$myProject = "DOC"

$cred = (Get-Credential)
[String] $Username = $Cred.UserName
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${Username}:$($Cred.GetNetworkCredential().Password)"))

$headers = @{    'Authorization' = "Basic $token" }

Invoke-WebRequest -Uri "$myServer/rest/api/2/project/$myProject" -Headers $headers -Method "GET" -UseBasicParsing | convertto-json
JoeJe1993 commented 7 years ago

image

lipkau commented 7 years ago
$myServer = "https://"
$myProject = "DOC"

$cred = (Get-Credential)
[String] $Username = $Cred.UserName
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${Username}:$($Cred.GetNetworkCredential().Password)"))

$headers = @{    'Authorization' = "Basic $token" }

try {
$webResponse = Invoke-WebRequest -Uri "$myServer/rest/api/2/project/$myProject" -Headers $headers -Method "GET" -UseBasicParsing
} catch {
$webResponse = $_.Exception.Response
}
$webResponse | convertto-json
JoeJe1993 commented 7 years ago

No error this time, literally nothing returned.

image

lipkau commented 7 years ago

$webresponse is empty??

lipkau commented 7 years ago
$myServer = "https://"

$cred = (Get-Credential)
[String] $Username = $Cred.UserName
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${Username}:$($Cred.GetNetworkCredential().Password)"))

$headers = @{    'Authorization' = "Basic $token" }

try {
$webResponse = Invoke-WebRequest -Uri "$myServer/rest/api/2/project" -Headers $headers -Method "GET" -UseBasicParsing
} catch {
$webResponse = $_.Exception.Response
}
$webResponse | convertto-json
JoeJe1993 commented 7 years ago

image

JoeJe1993 commented 7 years ago

image

JoeJe1993 commented 7 years ago

I have discovered that this may be an internal issue, I'll get back to you with further results shortly.

JoeJe1993 commented 7 years ago

UPDATE: So to get the API to work in my browser, I had to login manually via that same browser session.

It seems that the username and password in Get-Credential is not getting passed onto the API in your test script.

JoeJe1993 commented 7 years ago

image

JoeJe1993 commented 7 years ago

image

lipkau commented 7 years ago

Is it only on New-JiraIssue that that happens? Does Get-JiraIssue or Set-JiraIssue work on that project?

There must be going something on with the authentication... If you see the result in the browser, you should also get the same in the Invoke-WebMethod

I get the same result (error) as you when I don't authenticate (anonymous) - wrong credentials return a different error

bopper-ps commented 7 years ago

Hey guys, I would like to jump in here and let you know that I am getting the same error. image

lipkau commented 7 years ago

It appears that running the command Get-JiraIssueCreatMetadata is doing something differently when called be the user and by New-JiraIssue. I will investigate once I am at a pc

JoeJe1993 commented 7 years ago

Get-JiraIssue works perfectly fine.

JoeJe1993 commented 7 years ago

I can also confirm that Set-JiraIssue works. However, I had to specify the -Credential parameter twice in order to get it to work.

Get-JiraIssue -Key DOC-600 -Credential $Creds|Set-JiraIssue -Description "Test123" -Credential $Creds

JoeJe1993 commented 7 years ago

Hi @lipkau, any updates?

lipkau commented 7 years ago

What version of the module are you using? Get-Module PSJira -ListAvailable

lipkau commented 7 years ago

can you show me how this url looks in your browser? @JoeJe1993 : https://-----------------/rest/api/latest/issue/createmeta?projectIds=10100&issuetypeIds=10002&expand=projects.issuetypes.fields @JohnTheDon01 : https://-----------------/rest/api/latest/issue/createmeta?projectIds=11200&issuetypeIds=10301&expand=projects.issuetypes.fields