Forum Discussion

proxicon's avatar
proxicon
Icon for Altostratus rankAltostratus
Aug 23, 2022

Create a IFile {system level} via API - Powershell

Hi All,

Attempting the following:
1: Create iFile system level
2: Update existing iRule-> iFile referance the the file uploaded in step 1.

Im getting stuck at step 1, any assistance creatly apprecuated.
What I have tried:

Get Auth Token:

 

# Get API token
$big_ip          = 'https://[REDACTED]'
$url    = "{0}{1}" -f $big_ip, '/mgmt/shared/authn/login'
$body   = @{
    username = "[REDACTED]"
    password = '[REDACTED]'
    loginProviderName = "tmos"
} | ConvertTo-Json

$result = Invoke-RestMethod -Method 'POST' -Uri $url -ContentType 'application/json' -Body $body
$token = $($result.token.token)

 

Works.
Next, Upload my file:

 

$File_Name   = 'MyFile'
$File_Upload = 'C:\Temp\MyFile'
$url         = "{0}{1}{2}" -f $big_ip, "/mgmt/shared/file-transfer/uploads/", $File_Name
$filelength  = (Get-Item $File_Upload).length

$headers = @{
    'Content-Type' = 'application/octet-stream'
    'X-F5-Auth-Token' = $token
    'Content-Range' = "0-$($filelength-1)/$filelength"
}

$result = Invoke-RestMethod -Method Post -Uri $url -Headers $headers -InFile $File_Upload

 

Works fine too I am returned with:

 

remainingByteCount : 0
usedChunks         : @{0=46321}
totalByteCount     : 46321
localFilePath      : /var/config/rest/downloads/MyFile
temporaryFilePath  : /var/config/rest/downloads/tmp/MyFile
generation         : 0
lastUpdateMicros   : 1661257236246203

 

Next is where im stuck, creation of the iFile system level from the uploaded file.
Ive re-typed the below from the Curl samples here: Syncing local repositories and ifiles using iContr... - DevCentral (f5.com)

 

### Create a iFile {system level} - does not yet work
$File_Name = 'MyFile'
$url       = "{0}{1}{2}" -f $big_ip, "/mgmt/tm/sys/file/ifile/", $File_Name

$headers = @{
    'Content-Type'    = 'application/json'
    'X-F5-Auth-Token' = $token
}

$body = @{
    'name'            = $File_Name
    'source-path'     = "file:///var/config/rest/downloads/$File_Name"
} | ConvertTo-Json

$result = Invoke-RestMethod -Method put -Uri $url -Headers $headers -Body $body

 

Next I am recieving that the file cannot be found. So this query is incorrectly tructured ?
Translated these examples to powershell:
Syncing local repositories and ifiles using iContr... - DevCentral (f5.com)

 

Invoke-RestMethod : {"code":404,"message":"01020036:3: The requested iFile (/Common/MyFile) was not found.","errorStack":[],"apiError":3}
At line:1 char:11
+ $result = Invoke-RestMethod -Method put -Uri $url -Headers $headers - ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

 

 Any assistance appreated with the above & next up updating the iRule file refence.

  • proxicon's avatar
    proxicon
    Aug 24, 2022

    Found my fault... JRahm & Patrik_Jonsson this was after my long reply to your other post JRahm (and yes it works on a POST method)... I had the file name in the URL overload specified on the initial create request, it should not be in there...

    so this..

     

     

    $File_Name = 'MyFile'
    $url       = "{0}{1}{2}" -f $big_ip, "/mgmt/tm/sys/file/ifile/",$File_Name
    
    $headers = @{
        'Content-Type'    = 'application/json'
        'X-F5-Auth-Token' = $token
    }
    
    $body = @{
        'name'            = $File_Name
        'source-path'     = "file:/var/config/rest/downloads/$File_Name"
    } | ConvertTo-Json -Compress
    
    $result = Invoke-RestMethod -Method post -Uri $url -Headers $headers -Body $body 

     

     


    needs to be:

     

     

    $File_Name = 'MyFile'
    $url       = "{0}{1}" -f $big_ip, "/mgmt/tm/sys/file/ifile/"
    
    $headers = @{
        'Content-Type'    = 'application/json'
        'X-F5-Auth-Token' = $token
    }
    
    $body = @{
        'name'            = $File_Name
        'source-path'     = "file:/var/config/rest/downloads/$File_Name"
    } | ConvertTo-Json -Compress
    
    $result = Invoke-RestMethod -Method post -Uri $url -Headers $headers -Body $body

     

     

     without the file name in the initial overload.

    Hope this helps some future person 🙂 
    Off to the next challange.

    Bonus: Retyped to splat (overload definition) - because why not.

     

     

    # Create a IFile {system level} 
    $File_Name = 'MyFile'
    $Uri       = "{0}{1}" -f $big_ip, "/mgmt/tm/sys/file/ifile/"
    
    # Construct overload definition
    $Param_InvokeRestMethod = @{
        headers = @{
            'Content-Type'    = 'application/json'
            'X-F5-Auth-Token' = $token
        }
    
        body = @{
            'name'            = $File_Name
            'source-path'     = "file:/var/config/rest/downloads/$File_Name"
        } | ConvertTo-Json -Compress
    
        Method = 'post'
    
        Uri = $Uri
    }
    
    # Post & capture result
    $result = Invoke-RestMethod @Param_InvokeRestMethod

     

     

     

  • Hi there!

    Nice to see some Powershell users in the forum. 🙂 If you have validated that the file is actually there, try this to make sure that it's not SELinux that is tripping you up:

    restorecon -RvF <file path>

    Ps. Coming from Python2? Recommending string interpolation:

    $url = "{0}{1}{2}" -f $big_ip, "/mgmt/tm/sys/file/ifile/", $File_Name
    # Becomes
    $url = "$big_ip/mgmt/tm/sys/file/ifile/$File_Name"
    # A bit safer (less risk in terms of unintentionally referencing the wrong variable):
    $url = "$($big_ip)/mgmt/tm/sys/file/ifile/$($File_Name)"
    • JRahm's avatar
      JRahm
      Icon for Admin rankAdmin

      create method should be a post as well, not a put. Maybe that's what you have, as I don't speak powershell very well. 🙂

      For the python implementation of what you're trying to do, you can read the functional test of the python SDK here.

      And might I add, proxicon, that that's a very well asked question! Great details. THANK YOU!

    • Patrik_Jonsson's avatar
      Patrik_Jonsson
      Icon for MVP rankMVP

      Also, try this for the source-path property when creating the body:

      "file:/var/config/rest/downloads/$File_Name"
      # instead of
      "file:///var/config/rest/downloads/$File_Name"

       

      • proxicon's avatar
        proxicon
        Icon for Altostratus rankAltostratus

        Thanks Patrick, ive tried both variations before typing this initial post. Saw tht in a few other examples & as with all things code if the API docs did not deliver, we are on stack overflow or forums discussing alternatives 🙂 

        using file:/// or file:/ serves up the same API 400 exit 37

         

        Invoke-RestMethod : {"code":400,"message":"Failed! exit_code (37).\n","errorStack":[],"apiError":26214401}
        At line:1 char:11
        + $result = Invoke-RestMethod -Method put -Uri $url -Headers $headers - ...
        +           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
            + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

         

        This is with:

         

        $File_Name = 'MyFile'
        $url       = "{0}{1}{2}" -f $big_ip, "/mgmt/tm/sys/file/ifile/", $File_Name
        
        $headers = @{
            'Content-Type'    = 'application/json'
            'X-F5-Auth-Token' = $token
        }
        
        $body = @{
            'name'            = $File_Name
            'source-path'     = "file:/var/config/rest/downloads/tmp/$File_Name"
        } | ConvertTo-Json -Compress
        
        $result = Invoke-RestMethod -Method put -Uri $url -Headers $headers -Body $body

         

        Both instances the file upload occured & exists in:

         

        remainingByteCount : 0
        usedChunks         : @{0=46321}
        totalByteCount     : 46321
        localFilePath      : /var/config/rest/downloads/MyFile
        temporaryFilePath  : /var/config/rest/downloads/tmp/MyFile
        generation         : 0
        lastUpdateMicros   : 1661327626220187

         


        Point taken on the string formatting,  I flip between C# & Powershell quite ofen so the formatting is more a C# habbit than Python for me.

        All of these examples are "try before writinig a function" code so these samples arent set in stone & the eventual final solution & battle tested functions & modules will be written & deployed towards the end of this excersisise 🙂 (when I get the samples working)

        Thank for your reply.