For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

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

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

     

     

     

10 Replies

  • 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)"
    • 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.

    • 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!