Forum Discussion
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.
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)"
- JRahmAdmin
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!
- proxiconAltostratus
Thanks for your reply JRahm ,
I have tried a Post as opposed to a Put method call & the API return message is different. Maybe a hint at what im doing wrong ?With Put:
{"code":400,"message":"Failed! exit_code (37).\n","errorStack":[],"apiError":26214401}
With Post:
{"code":400,"message":"Found unexpected URI tmapi_mapper/sys/file/ifile/MyFile.","errorStack":[],"apiError":1}
I can add that my authenticated user I get the API token with is a radius authenticated user and not local. The only diff ive seen with thee Curl examples ive followed/mentioned here + the python wrapper mentionred (which I tried to re-type to powershell as well) are that they use a local user with the "Authentication: Basic user:pass" header as opposed to 'X-F5-Auth-Token' in the header which im using.
I can manually create a system level iFile manually in the UI with this radius user (this is what im trying to automate via the API) & use the iControl Reest API to upload new content into the iFile, this works for me using the X-F5-Auth-Token radius user. So the writing of new content to an existing iFile works for me but not the creation thereof not.
I have access to a few/newer F5-LTM, my network SME granted me access to a V15.1.5 F5-LTM to rule out a possible issue with the F5 12.1.5 im working with at the minute (K69621049) which was resolved in revision 12.1.5 I initially thought that this was my issue. Both revisions of F5 I can test against (15.1.5 & 12.1.5) Im observing the exact same return codes from the API as at the top of this post.
Taken the above into account, can this be an issue for me that the radius / remote user might have an issue on this method of the API & is it worth asking my network SME to try create a local account to rule this out?
Ive tried constructing the "Authentication: Basic user:pass" header with my radius user but get a 401 authentication failed. So I feel I needed to specify this in the initial post but it was omitted due to loads of typing 🙂Invoke-RestMethod : {"code":401,"message":"Authorization failed: user=https://localhost/mgmt/shared/authz/users/MyUser resource=/mgmt/tm/sys/file/ifile/MyFile verb=POST uri:http://localhost:8100/mgmt/tm/sys/file/ifile/MyFile [REDACTEDIP]referrer:[REDACTEDIP]sender:[REDACTEDIP]","referer":"[REDACTEDIP]","restOperationId":122408205,"errorStack":["java.lang.SecurityException: Authorization failed: user=https://localhost/mgmt/shared/authz/users/ccfortinetsrv resource=/mgmt/tm/sys/file/ifile/MyFile verb=POST uri:http://localhost:8100/mgmt/tm/sys/file/ifile/MyFile referrer:[REDACTEDIP] sender:[REDACTEDIP]","at com.f5.rest.workers.EvaluatePermissions.failPermissionValidation(EvaluatePermissions.java:236)","at com.f5.rest.workers.EvaluatePermissions.completeEvaluatePermission(EvaluatePermissions.java:198)","at com.f5.rest.workers.EvaluatePermissions.evaluatePermission(EvaluatePermissions.java:78)","at com.f5.rest.workers.ForwarderPassThroughWorker.onForward(ForwarderPassThroughWorker.java:227)","at com.f5.rest.workers.ForwarderPassThroughWorker.onPost(ForwarderPassThroughWorker.java:502)","at com.f5.rest.common.RestWorker.callDerivedRestMethod(RestWorker.java:1120)","at com.f5.rest.common.RestWorker.callRestMethodHandler(RestWorker.java:1034)","at com.f5.rest.common.RestServer.processQueuedRequests(RestServer.java:1355)","at com.f5.rest.common.RestServer.access$000(RestServer.java:45)","at com.f5.rest.common.RestServer$1.run(RestServer.java:316)","at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)","at java.util.concurrent.FutureTask.run(FutureTask.java:262)","at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)","at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)","at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)","at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)","at java.lang.Thread.run(Thread.java:748)\n"],"kind":":resterrorresponse"} At line:1 char:11
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"
- proxiconAltostratus
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 37Invoke-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.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com