XCP-ng
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login

    XEN Orchestra JSON-RPC automation questions

    Scheduled Pinned Locked Moved Unsolved Infrastructure as Code
    json-rpspowershell 5websocketautomationdeployclone
    8 Posts 4 Posters 257 Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • I Offline
      IvanK
      last edited by IvanK

      Hello.

      We already have VM deploy tool written in powershell 5. And now we need to add there support for XCP-NG.
      REST API does not provide neither clone nor methods for change VM properties (but name and description, so I had to use websockets.

      But I face several issues:

      1. When I call vm.clone method I can see in corresponding task that it fails with “SR_BACKEND_FAILURE_1200(, Invalid argument, )” error, never mind that sr is not needed for clone. here is reference from our XCP about this method:
      "vm.clone": {
        "params": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "full_copy": {
            "type": "boolean"
          }
        }
      },
      

      I tried to use parameters with SR or without - does not matter - it didn't work, same as I tried to use parameters like

      VM = vm_id
          name_label = "NEW_VM_BY_API"
          name_description = "NEW_VM_BY_API"
          snapshot = "false"
          full_copy = "true"
          sr = sr_id
      

      it also did not help.

      What correct parameters should be to run vm.clone method via websocket json_rpc?

      1. I was able sucecssfully call method vm.copy with parameters
      $vm_copy = @{
          vm = vm_id
          name = "NEW_VM_BY_API"
          sr = 'sr_id'
      }
      

      and it worked, but how can I track process programmaticaly and how it finished?

      there're no methods for tasks, but task.cancel or task.destroy. I can query xo.getAllObjects with filter "task", but it returns only pending tasks and just failed ones (and for single copy task there're two tasks in output. very similar) As soon as task completes succesfully - it disappears from getAllObjects. And even if it fails - it also disappeares from there but after some time. Why there're no info about successfully completed tasks? Where can I found those logs?

      I can see more failed tasks in REST output in /rest/v0/tasks (no sign of successfull ones either), but I cannot find correspondence between task GUID in json_rpc and task id that some type of base_encode in REST so it is very hard to determine that deploy completed successfully
      I can query each failed task in /rest/v0/tasks/GUID in cycles to find mine, but it sounds awful. And if one task failed for the first time and I will do restart - it will find in REST old failed tasks with the same info, so I need to rely on something else. Timestamps?

      Not very convenient for sure.

      I feel that I am missing something and hope that you can help me automating my deploys on XCP-NG platform using powershell 5.

      all methods I have I received using ws call method 'system.getMethodsInfo'

      Here powershell code for websocket queries if you like:

      function Call-XOJsonRpc
      {
          param(
              [string]$uri,
              [string]$username,
              [string]$password,
              [string]$method,
              [hashtable]$parameters = @{}
          )
          $ct = [System.Threading.CancellationToken]::None
          $client = [System.Net.WebSockets.ClientWebSocket]::new()
      
          try {
              # Connect to WebSocket
              $client.ConnectAsync([System.Uri]$uri, $ct).Wait()
              Write-Host "Connected to XO WebSocket"
      
              function Send-JsonRpc {
                  param (
                      [string]$method,
                      [hashtable]$params = @{},
                      [int]$id
                  )
      
                  $json = @{
                      jsonrpc = "2.0"
                      method  = $method
                      params  = $params
                      id      = $id
                  } | ConvertTo-Json -Depth 5 -Compress
      
                  $bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
                  $segment = [System.ArraySegment[byte]]::new($bytes)
                  $client.SendAsync($segment, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $ct).wait()
              }
      
              function Receive-JsonRpc {
                  $buffer = New-Object byte[] 8192
                  $segment = [System.ArraySegment[byte]]::new($buffer)
                  $textBuilder = New-Object System.Text.StringBuilder
      
                  do {
                      $result = $client.ReceiveAsync($segment, $ct).Result
                      $chunk = [System.Text.Encoding]::UTF8.GetString($buffer, 0, $result.Count)
                      $null = $textBuilder.Append($chunk)
                  } while (-not $result.EndOfMessage)
      
                  return $textBuilder.ToString()
              }
      
              # 2. session.signIn
              Send-JsonRpc -method "session.signIn" -params @{ username = $username; password = $password } -id 1
              $loginResponse = Receive-JsonRpc | ConvertFrom-Json
              if ($loginResponse.error) {
                  throw "Login failed: $($loginResponse.error.message)"
              }
      
              Write-Host "Logged in to XO WebSocket successfully"
      
              Send-JsonRpc -method $method -id 2 -params $parameters 
              $objResponse = (Receive-JsonRpc).tolower()| ConvertFrom-Json
      
              return $objResponse
      
          } catch {
              Write-Error "Error: $_"
          } finally {
              if ($client.State -eq [System.Net.WebSockets.WebSocketState]::Open) {
                  
                  $result = $client.CloseAsync([System.Net.WebSockets.WebSocketCloseStatus]::Empty, "", $ct)
                  Start-Sleep -Seconds 5
                  if ($client.State -eq [System.Net.WebSockets.WebSocketState]::Open)
                  {
                      throw "Cannot close websocket connection"
                  }
              }
              $client.Dispose()
          }
      
      }
      

      example

      $username = "yourusername"
      $password = 'yourpassword'
      
      $task_info = @{
          filter = @{
              type = "task"
          }
      }
      
      $result_tasks = Call-XOJsonRpc -uri 'ws://URL/api/' -username $username  -password $password -method "xo.getAllObjects" -parameters $task_info
      
      output like:
      
      ($result_tasks.result.PSObject.Properties.Value |ForEach-Object { $_ | ConvertTo-Json -Depth 5 })|ConvertFrom-Json
      
      1 Reply Last reply Reply Quote 0
      • olivierlambertO Offline
        olivierlambert Vates 🪐 Co-Founder CEO
        last edited by

        Ping @Team-DevOps

        nathanael-hN 1 Reply Last reply Reply Quote 0
        • nathanael-hN Offline
          nathanael-h Vates 🪐 DevOps Team @olivierlambert
          last edited by

          Hello @IvanK !

          Maybe you did not saw this in news, but we released a PowerShell module https://github.com/vatesfr/xo-powershell

          You can install it with Install-Module -Name xo-powershell -AllowPrerelease and connect Connect-XoSession -HostName "https://your-xo-server" -Token "your-api-token" easily.

          Tell me what do you think of it.

          I 1 Reply Last reply Reply Quote 1
          • I Offline
            IvanK @nathanael-h
            last edited by IvanK

            @nathanael-h Unfortunately xo-powershell is RESTAPI and there're no clone or set vm CPU/MEM/HDD possibilities in REST.
            If you can let us know rule - how task GUID (that we somehow can get from websocket querying all xo objects) is converted into taskID that we can see in REST - it would help a bit

            olivierlambertO 1 Reply Last reply Reply Quote 0
            • nathanael-hN Offline
              nathanael-h Vates 🪐 DevOps Team
              last edited by

              Hello, a community member also built a PowerShell module, using the (good old) jsonRPC https://github.com/rcfmartin/PSXO

              let me ask a colleague about the task GUID-taskID mapping.

              I 1 Reply Last reply Reply Quote 0
              • olivierlambertO Offline
                olivierlambert Vates 🪐 Co-Founder CEO @IvanK
                last edited by

                @IvanK said in XEN Orchestra JSON-RPC automation questions:

                @nathanael-h Unfortunately xo-powershell is RESTAPI and there're no clone or set vm CPU/MEM/HDD possibilities in REST.
                If you can let us know rule - how task GUID (that we somehow can get from websocket querying all xo objects) is converted into taskID that we can see in REST - it would help a bit

                Also, the missing calls in the REST API can be added relatively soon (it's triggered by the actual demand). Pinging @lsouai-vates so we can plan this in a next release.

                lsouai-vatesL 1 Reply Last reply Reply Quote 0
                • lsouai-vatesL Offline
                  lsouai-vates Vates 🪐 XO Team @olivierlambert
                  last edited by

                  @olivierlambert it is planned 🙂
                  @IvanK We're gradually migrating endpoints to the REST API and will create new ones later.
                  I know it can be frustrating not having everything ready to use, and we understand that... We do our best

                  1 Reply Last reply Reply Quote 1
                  • I Offline
                    IvanK @nathanael-h
                    last edited by

                    @nathanael-h thanks a lot! This jsonrpc module looks like it is what do we want. Hope it will do the trick

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post