【问题标题】:Create Team City Build configurations using restapi and powershell使用 rest api 和 powershell 创建 Teamcity Build 配置
【发布时间】:2015-09-11 00:42:08
【问题描述】:

我正在尝试通过 restapi 和 powershell 创建构建配置并不断收到以下错误:

使用“0”参数调用“GetResponse”的异常:“远程服务器返回错误:(405) 方法不允许。”

看来我可以使用GET 很好,问题似乎与PUT 命令有关

代码片段

$url = http://%teamcityServer%:8111/app/rest/buildTypes/id:%projectname%"
$req = [System.Net.WebRequest]::Create($url)
$req.ContentType = "text/plain"
$req.UseDefaultCredentials = $true
$req.Credentials = Get-Credential("username")
$req.Method ="PUT"
$req.ContentLength = 0
$req.Accept = "*/*"
$resp = $req.GetResponse()
$results = [xml]$resp.ReadToEnd()

Team City 日志的输出

2015-09-10 09:14:30,582] WARN [io-8111-exec-70] - est.jersey.ExceptionMapperUtil - 请求处理期间发生错误 (405)。错误:javax.ws.rs.WebApplicationException。不支持的请求。请检查 URL、HTTP 方法和传输的数据是否正确。元数据:[允许:[HEAD,DELETE,GET,OPTIONS],] 请求:PUT '/app/rest/buildTypes/id:%project%'

Team City 版本是 9.1.1,所以我相信这是可能的。

我对 restapi 还很陌生,因此欢迎任何意见。

【问题讨论】:

    标签: rest powershell teamcity


    【解决方案1】:

    这是可能的,但您需要发布 xml 数据来创建构建/项目。例如,如果您需要创建一个项目,您可以 POST XML 类似

    <newProjectDescription name='New Project Name' id='newProjectId' copyAllAssociatedSettings='true'><parentProject locator='id:project1'/><sourceProject locator='id:project2'/></newProjectDescription>
    

    http://teamcity:8111/httpAuth/app/rest/projects

    查看Teamcity REST documentation的更多信息。

    您没有提及您的 powershell 版本,但如果您使用的是 3.0 或更高版本,则可以调用 Invoke-WebRequest cmdlet,您的代码应如下所示:

    Invoke-WebRequest -Uri $uri -Credential $cred -Method Post -Body $body -ContentType "Application/xml"
    

    对于 PowerShell 2.0,您可以编写自己的 Web-Request 方法,例如:

    function Web-Request{   
        param(
            [Parameter(Mandatory=$true)]
            [string]
            $Uri,
    
            [Parameter(Mandatory=$false)]
            [string]
            $Username = $null,
    
            [Parameter(Mandatory=$false)]
            [string]
            $Password = $null,      
    
            [Parameter(Mandatory=$true)]
            [string]
            $ContentType,
    
            [Parameter(Mandatory=$true)]
            [string]
            $Method,
    
            [Parameter(Mandatory=$false)]
            [string]
            $PostString
        )
    
        $webRequest = [System.Net.WebRequest]::Create($Uri)
        $webRequest.ContentType = $ContentType  
        $webRequest.Method = $Method
        $webRequest.Accept = "*/*"
        if ($Username)
        {
            $webRequest.Credentials = new-object system.net.networkcredential($Username, $Password)
        }
    
        try
        {
            switch -regex ($Method)
            {
                "PUT|POST" # PUT and POST behaves similar ways except that POST is only used for creation while PUT for creation/modification   
                {
                    if ($PostString -ne "")
                    {       
                        $PostStringBytes = [System.Text.Encoding]::UTF8.GetBytes($PostString)
                        $webrequest.ContentLength = $PostStringBytes.Length
                        $requestStream = $webRequest.GetRequestStream()
                        $requestStream.Write($PostStringBytes, 0,$PostStringBytes.length)
                    }
                    else
                    {
                        $requestStream = $webRequest.GetRequestStream()
                    }
                }
                "DELETE"
                {
                    $requestStream = $webRequest.GetRequestStream()
                }
                default
                {               
                    # GET requests usually don't have bodies, default will behave like a GET
                }
            }
    
            if ($requestStream -ne $null)
            {       
                $requestStream.Close()
            }
    
            [System.Net.WebResponse] $resp = $webRequest.GetResponse();
            $rs = $resp.GetResponseStream();
            [System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
            [string] $results = $sr.ReadToEnd();
        }
        catch
        {
            $results = "Error : $_.Exception.Message"
        }
        finally
        {   
            if ($sr -ne $null) { $sr.Close(); }
            if ($resp -ne $null) { $resp.Close(); }
    
            $resp = $null;
            $webRequest = $null;
            $sr = $null;
            $requestStream = $null;
        }
        return $results 
    }
    

    【讨论】:

    • 好的,谢谢,它实际上是 PowerShell v2.0。这导致我使用 webrequest 我会尝试将其更新到更高版本。我假设 $body 将是您发布的 xml?
    • 是的 $body 是用于构建/项目创建的 XML。我已经更新了答案并添加了一个 Web-Request 方法来使用 PowerShell 2.0。
    • 感谢 Nadeem,我现在似乎在以下行出现错误 [System.Net.WebResponse] $resp = $webRequest.GetResponse();错误:使用“0”参数调用“GetResponse”的异常:“远程服务器返回错误:(500)内部服务器错误。”.Exception.Message
    • 更新:现在可以了。感谢您的帮助 Nadeem
    猜你喜欢
    • 1970-01-01
    • 2014-06-23
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    相关资源
    最近更新 更多