简体   繁体   中英

JIRA REST API gives HTTP error 400 with PowerShell v3

I'm attempting to write some PowerShell functions to interface with our Atlassian JIRA system (JIRA 5.2, download version). Unfortunately, I've found through trial and error that the Invoke-RestMethod doesn't seem to work (doesn't support authentication headers), so I've written up a simple function called Invoke-JiraMethod. I can confirm that this method works for GET requests; I've been able to use it to get Jira objects to my heart's desire. As soon as I tried to create an issue, though, I started getting a HTTP 400 / Bad request error.

I've followed the steps here to get my issue metadata, and I'm filling out all the required fields in my input object. Could anyone help me figure out how to solve the 400 error? I can provide more information if needed - I just didn't want to overflow the description of the question. :)

Function Invoke-JiraMethod
{
    <#
    .Synopsis
        Low-level function that directly invokes a REST method on JIRA
    .Description
        Low-level function that directly invokes a REST method on JIRA.  This is designed for 
        internal use.
    #>
    [CmdletBinding()]
    param
    (
        [ValidateSet("Get","Post")] [String] $Method,
        [String] $URI,
        [String] $Username,
        [String] $Password
    )

    process
    {
        $token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${Username}:${Password}"))

        $webRequest = [System.Net.WebRequest]::Create($URI)
        $webRequest.Method = $Method.ToUpper()

        $webRequest.AuthenticationLevel = "None"
        $webRequest.Headers.Add('Authorization', "Basic $token")
        #$webRequest.Headers.Add('Authorization', $token)
        $webRequest.PreAuthenticate = $true
        $webRequest.ContentType = "application/json"

        Write-Verbose "Invoking JIRA method $Method with URI $URI"
        $response = $webRequest.GetResponse()
        $requestStream = $response.GetResponseStream()
        $readStream = New-Object -TypeName System.IO.StreamReader -ArgumentList $requestStream
        $json = $readStream.ReadToEnd()
        $readStream.Close()
        $response.Close()

        $result = $json | ConvertFrom-Json

        Write-Output $result
    }
}

Function New-JiraIssue
{
    param
    (
        [Parameter(Mandatory = $true,
                   Position = 0)]
        [string] $ProjectKey,

        [Parameter(Mandatory = $true,
                   Position = 1)]
        [string] $IssueType,

        [Parameter(Mandatory = $false)]
        [string] $Priority = 3,

        [Parameter(Mandatory = $true,
                   Position = 2)]
        [string] $Summary,

        [Parameter(Mandatory = $true,
                   Position = 3)]
        [string] $Description,

        [Parameter(Mandatory = $true,
                   Position = 4)]
        [string] $Location,

        [Parameter(Mandatory = $true,
                   Position = 5)]
        [string] $Phone,

        [Parameter(Mandatory = $false)]
        [string] $Reporter,

        [Parameter(Mandatory = $false)]
        [PSCredential] $Credential
    )

    process
    {
        $ProjectObject = New-Object -TypeName PSObject -Property @{"key"=$ProjectKey}
        $IssueTypeObject = New-Object -TypeName PSObject -Property @{"id"=$IssueType}

        if ( -not ($Reporter))
        {
            Write-Verbose "Reporter not specified; defaulting to $JiraDefaultUser"
            $Reporter = $JiraDefaultUser
        }

        $ReporterObject = New-Object -TypeName PSObject -Property @{"name"=$Reporter}

        $fields = New-Object -TypeName PSObject -Property ([ordered]@{
            "project"=$ProjectObject;
            "summary"=$Summary;
            "description"=$Description;
            "issuetype"=$IssueTypeObject;
            "priority"=$Priority;
            "reporter"=$ReporterObject;
            "labels"="";
            $CustomFields["Location"]=$Location;
            $CustomFields["Phone"]=$Phone;
            })


        $json = New-Object -TypeName PSObject -Property (@{"fields"=$fields}) | ConvertTo-Json

        Write-Verbose "Created JSON object:`n$json"

        # https://muwebapps.millikin.edu/jira/rest/api/latest/issue/IT-2806
        # $result = Invoke-RestMethod -Uri $JiraURLIssue -Method Post -ContentType "application/json" -Body $json -Credential $Credential

        if ($Username -or $Password)
        {
            $result = (Invoke-JiraMethod -Method Post -URI "${JiraURLIssue}" -Username $Username -Password $Password)
        } else {
            $result = (Invoke-JiraMethod -Method Post -URI "${JiraURLIssue}" -Username $JiraDefaultUser -Password $JiraDefaultPassword)
        }

        Write-Output $result
    }
}

Thanks in advance!

I was receiving the error 400 because the issue type id number I had put into the json data wasn't mapped to anything. fiddler helped me diagnose that.

I used this bit of code to figure out authenticating to jira via invoke-restmethod's -Headers option: http://poshcode.org/3461

then I put the json data into a here string, and ran invoke-restmethod.

code bits below. replace "any valid... type id number" with actual project and issue type ids you get from your jira admin.

$uri = "$BaseURI/rest/api/2/issue" 


    $jsonString = @'
{
    "fields": {
       "project":
       {
          "id": "any valid project id number"
       },
       "summary": "No REST for the Wicked.",
       "description": "Creating of an issue using ids for projects and issue types using the REST API",
       "issuetype": {
          "id": "any valid issue type id number"
       }
   }
}  
'@  


        $headers = Get-HttpBasicHeader $Credentials

        Invoke-RestMethod -uri $uri -Headers $headers  -Method Post -Body $jsonString -ContentType "application/json"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM