e-xpertsolutions / f5-rest-client Goto Github PK
View Code? Open in Web Editor NEWF5 BIG-IP SDK for the Go programming language.
License: BSD 3-Clause "New" or "Revised" License
F5 BIG-IP SDK for the Go programming language.
License: BSD 3-Clause "New" or "Revised" License
Hi,
I have this scenario where I need to schedule the job at will run at specific time, but one of the requirements is to use token. However we use RSA as means of authentication, so the problem is if I schedule the job at 2am this will be a problem is there a way to pre-generate the token and use the token ? I hope that makes sense.
Hi, I want the Get method to get the names of the poolmembers, However, I don't know what values are passed in for pool and id, can you explain it to me? The specific function is as follows:
https://pkg.go.dev/github.com/e-XpertSolutions/[email protected]/f5/ltm#PoolMembersResource.Get
The F5 API does not return the cachePath field by default, an extra parameter ?option=-hidden
must be provided. Such option must be supported by sys.FileSSLCertConfig
, the List*
and Get
methods.
For instance: https://my.f5.com/manage/s/article/K67050204
A lot of method are using an id
, which references an object on the BIG-IP (e.g. /Common/foobar). Such id
is composed of a partition name and the actual object name. iControl REST are using ~Common~foobar
to create such a reference and just using a plain string is not necessarily the best.
A structure like ObjectID
would make things a lot easier:
type ObjectID string
func NewObjectID(partition, name string) ObjectID {
if partition == "" {
partition = "Common"
}
return ObjectID("~" + partition + "~" + name)
}
func ParseObjectID(fullname string) ObjectID {
return ObjectID(strings.Replace(fullname, "/", "~", -1))
}
func (oid ObjectID) Partition() string {
idx := strings.LastIndex(string(oid), "~")
if idx == -1 {
return ""
}
return string(oid)[1:idx]
}
func (oid ObjectID) Name() string {
idx := strings.LastIndex(string(oid), "~")
if idx == -1 {
return ""
}
return string(oid)[idx+1:]
}
func (oid ObjectID) String() string {
return strings.Replace(string(oid), "~", "/", -1)
}
(note that this is just a prototype, not the final implementation)
This feature should be implemented in the next release (v1.0.0) in order not to break any existing implementation using the f5-rest-client
.
In the current F5 GTM rest client, there is no support to enable ECS (EDNS client subnet) on a WideIP. Is there a plan to enable this feature.
hi,
I want to get its pool member list through the pool name of SourceAddressTranslation. I can't do it through the following code, and I haven't found the corresponding method. What should I do? code show as below:
package main
import (
"fmt"
"github.com/e-XpertSolutions/f5-rest-client/f5"
"github.com/e-XpertSolutions/f5-rest-client/f5/ltm"
"log"
"net/url"
"strings"
)
func main() {
f5Client, err := f5.NewBasicClient("https://192.168.5.134", "admin", "admin")
if err != nil {
log.Fatal(err)
}
f5Client.DisableCertCheck()
// Start new transaction.
tx, err := f5Client.Begin()
if err != nil {
log.Fatal(err)
}
ltmClient := ltm.New(tx)
params := url.Values{}
params.Set("expandSubcollections", "true")
vslist, _ := ltmClient.Virtual().ListAllWithParams(params)
var test string
for _, value := range vslist.Items {
test = value.SourceAddressTranslation.Pool
//fmt.Println(test)
}
satpoollist := StringSplitSubStrings(test)
satPoolList, _ := ltmClient.PoolMembers().ListAll(satpoollist)
for _, v := range satPoolList.Items {
fmt.Println(v.Address)
}
}
func StringSplitSubStrings(src string) (des string) {
str := strings.SplitN(src, "/", -1)
return str[len(str)-1]
}
This also applies to jsonfilter, I guess this got introduced during local development?
Is there a plan to Open Source that part? Thanx!
I use f5-rest-Client through Gomod, but the code I pull is not what I submit(https://github.com/e-XpertSolutions/f5-rest-client/blob/master/f5/ltm/pool_stats.go)
my go.mod is:
go 1.14
require (
github.com/e-XpertSolutions/f5-rest-client v0.1.0
github.com/gogf/gf v1.13.4
github.com/hpifu/go-kit v1.8.7
)
Hi, I want to delete all the configurations in the virtualserver under partition, it doesn't seem to work, I don't know how to do it? My code is as follows:
package main
import (
"fmt"
"github.com/e-XpertSolutions/f5-rest-client/f5"
"github.com/e-XpertSolutions/f5-rest-client/f5/ltm"
"log"
"sort"
"time"
)
const Partition = "test"
//initiable f5 client
func NewF5Client() (*f5.Client, error) {
//hosts := fmt.Sprintf("https://" + Host)
//client, err := f5.NewBasicClient(hosts, Username, Password)
client, err := f5.NewBasicClient("https://192.168.10.83", "admin", "admin")
client.DisableCertCheck()
client.SetTimeout(60 * time.Second)
if err != nil {
fmt.Println(err)
}
return client, nil
}
func DeleteVS(client *f5.Client) (err error) {
tx, err := client.Begin()
if err != nil {
log.Fatalf("client open transaction: %s", err)
}
part := fmt.Sprintf("cd /%s", Partition)
output, _ := tx.ExecTMSH(part)
fmt.Println(output)
cmd := fmt.Sprintf("delete ltm virtual all")
outputs, _ := tx.ExecTMSH(cmd)
fmt.Println(outputs)
if err = tx.Commit(); err != nil {
log.Fatalf("client commits transaction: %s", err)
}
return nil
}
func main() {
client, _ := NewF5Client()
DeleteVS(client)
}
As a result, only the virtualserver whose partition is common can be deleted, and the virtualserver configuration of other partitions cannot be deleted.
I am hitting error with this code:
f5Client, errOpen := f5.NewBasicClient(f5Host, username, password)
ltmClient := ltm.New(f5Client)
poolClient := ltmClient.Pool()
poolList, errPoolList := poolClient.ListAll()
errPoolList hits this error:
json: cannot unmarshal string into Go struct field Pool.partition of type int64
the bash resource run function makes a request, but incorrectly names the variable "resp", and never calls "br.c.Do(req)"
The object returned is basically the same bashcommand object that is put into the function.
I have a sample code using the UploadFile to upload BIGIP ISO image, it always failed at sending 534249472 bytes. I used python script to upload BIGIP ISO image and it works, does not seem to be BIGIP issue.
sample code below:
package main import ( "flag" "fmt" "github.com/e-XpertSolutions/f5-rest-client/f5" "log" "os" "path/filepath" ) func main() { // give an ip at command line ip := flag.String("ip", "127.0.0.1", "BIGIP mgmt ip") user := flag.String("user", "admin", "BIGIP login user") password := flag.String("password", "admin", "BIGIP login password") iso := flag.String("iso", "/home/vincent/BIGIP-13.0.0.0.0.1645.iso", "iso file to upload") flag.Parse() // setup F5 BigIP client f5Client, err := f5.NewBasicClient("https://"+*ip, *user, *password) if err != nil { log.Fatal(err) } f5Client.DisableCertCheck() info, err := os.Stat(*iso) log.Println("iso size %d", info.Size()) if err != nil { fmt.Errorf("failed to gather information about '%s': %v", *iso, err) } f, err := os.Open(*iso) if err != nil { fmt.Errorf("failed to read file from path: %v", err) } defer f.Close() if _, err = f5Client.UploadFile(f, filepath.Base(*iso), info.Size()); err != nil { fmt.Errorf("failed to upload image file: %v", err) } }
I need to make a one-line change in upload.go to use the PathUploadImage "/mgmt/cm/autodeploy/software-image-uploads"
diff --git a/f5/upload.go b/f5/upload.go index 0e8c32e..f104770 100644 --- a/f5/upload.go +++ b/f5/upload.go @@ -48,7 +48,7 @@ func (c *Client) UploadFile(r io.Reader, filename string, filesize int64) (*Uplo chunk = remainingBytes } - req, err := c.MakeUploadRequest(PathUploadFile+"/"+filename, io.LimitReader(r, chunk), bytesSent, chunk, filesize) + req, err := c.MakeUploadRequest(PathUploadImage+"/"+filename, io.LimitReader(r, chunk), bytesSent, chunk, filesize) if err != nil { return nil, err }
Hello!
Do you have an example of initializing a nested struct such as the Pools field on the Wideip struct? I've tried various different ways and I'm unable to make it work. Is there a reason why you wouldn't make this field use one of your custom types instead of a slice of structs?
Thank you and keep up the great work!
Hi,
Would it be possible to release a new version (i.e. add a new tag, v0.1.0
, for example)?
Both dep
and go mod
depend on such tags to manage dependencies.
The latest release of this repo seems to be v0.0.0
from two years ago, meaning that this library can't currently be used without checking out the repo each time you wan't to use it.
Thanks.
Would it be possible to allow a way for a user to pass as a parameter their own http.Client
or http.RoundTripper
when creating the Client
with NewBasicClient
or NewTokenClient
?
See https://github.com/e-XpertSolutions/f5-rest-client/blob/master/f5/client.go
Example use cases include adding the ability to add in log functions to log requests and responses or to be able to customize #TLSClientConfig
.
hi, @gilliek
I want to get the snat member list attribute in ltm, what should I do? We don't see the corresponding method of struct?
Hi,
Would you be supporting this for version 13, as it seems like in version 12/13 icrd has been removed.
2017/11/01 16:10:13 &{[{} {} {}] tm:gtm:pool:a:acollectionstate https://localhost/mgmt/tm/gtm/pool/a?ver=13.0.0}
that is output I get from do tmPool.PoolA().ListAll()
thanks.
I find this document: https://devcentral.f5.com/s/articles/go-library-to-manage-big-ip-icontrol-rest-api-925?t=1638108790162
and this GitHub repository, at the same time I still find another repo: https://github.com/scottdware/go-bigip
I am a bit confused, what are the differences between two repositories and functions?
could you give me some hints, thanks.
when i connected f5 address using my username and password, i got an error,but my address ,username,password are all right
'f5Client check err authentication verification failed: Get "https://172.31.41.50:10443/mgmt/tm": x509: certificate signed by unknown authority'
url := "https://172.31.41.50:10443"
f5Client, err := f5.NewBasicClient(url, "username", " password")
if err != nil{
fmt.Println("f5Client err",err.Error())
}
checkerr := f5Client.CheckAuth()
if checkerr != nil{
fmt.Println("f5Client check err",checkerr.Error())
}
Hi,
Congrats for this amazing package!
For methods that require an "id" parameter for identifying the particular configuration object (such as get or modify), does your package provide a mechanism for obtaining it programmatically? I was able to deduce that the format of this parameter should be "~partitionName~objectName" but I am wondering whether your package provides a better way than assemblying this by hand. I also suggest that you document this somewhere :-)
Thanks!
Sample script:
// Create a Virtual Server log.Print("Create a Virtual Server") vsConfig := ltm.VirtualServer{ Name: "vs_http_" + tx.TransactionID(), Destination: "10.1.20.130:80", IPProtocol: "tcp", Pool: "pool_" + tx.TransactionID(), SourceAddressTranslation: ltm.SourceAddressTranslation{ Type: "automap", }, Profiles: []ltm.Profile{ //<=====HERE struct type Profile { Name: "tcp-mobile-optimized", Context: "all", }, { Name: "http", }, }, } if err := ltmClient.Virtual().Create(vsConfig); err != nil { log.Fatal(err) }
I think Profiles in VirtualServer struct should be []Profile, not []string
diff --git a/f5/ltm/virtual.go b/f5/ltm/virtual.go index 623088b..4c19f97 100644 --- a/f5/ltm/virtual.go +++ b/f5/ltm/virtual.go @@ -52,8 +52,8 @@ type VirtualServer struct { IsSubcollection bool `json:"isSubcollection,omitempty"` Link string `json:"link,omitempty"` } `json:"policiesReference,omitempty"` - Pool string `json:"pool,omitempty"` - Profiles []string `json:"profiles,omitempty"` // only used to link existing profiles a creation or update + Pool string `json:"pool,omitempty"` + Profiles []Profile `json:"profiles,omitempty"` // only used to link existing profiles a creation or update
hi,
I want to get the profiles name, however, I have configured the profiles related parameters on the f5 device, but I cannot get the profiles name. The following is my test code:
package main
import (
"encoding/json"
"fmt"
"github.com/e-XpertSolutions/f5-rest-client/f5"
"github.com/e-XpertSolutions/f5-rest-client/f5/ltm"
"log"
)
func main() {
f5Client, err := f5.NewBasicClient("https://192.168.5.134", "admin", "admin")
if err != nil {
log.Fatal(err)
}
f5Client.DisableCertCheck()
// Start new transaction.
tx, err := f5Client.Begin()
if err != nil {
log.Fatal(err)
}
ltmClient := ltm.New(tx)
vslist, _ := ltmClient.Virtual().ListAll()
for _, value := range vslist.Items {
b, err := json.Marshal(value.ProfilesReference.Profiles)
if err != nil {
log.Fatal(err)
}
t := string(b)
fmt.Println(t) // null
}
}
Hello, I always get: "Unable to commit transaction: Missing transaction ID for this call. (Code: 404)" error when I create pools and members, however, in f5 ltm I can see that the data is uploaded, how to solve this problem ?
My question is based on this kb article and api doc:
https://my.f5.com/manage/s/article/K67050204
https://clouddocs.f5.com/api/icontrol-rest/APIRef_tm_sys_file_ssl-cert.html
I expected there to be cachePath property on FileSSLCertConfig based on the KB above.
Is there another type I'm not seeing that exposes this property or is there a way to add that 'hidden' query parameter option?
The statistics information used to count the connection number of members under pool is the code that does not have this part, right?
example:
https://localhost/mgmt/tm/ltm/pool/zf/members/stats
{"kind":"tm:ltm:pool:members:memberscollectionstats","selfLink":"https://localhost/mgmt/tm/ltm/pool/zf/members/stats?ver=13.1.0.6","entries":{"https://localhost/mgmt/tm/ltm/pool/zf/members/~Common~zf/stats":{"nestedStats":{"kind":"tm:ltm:pool:members:membersstats","selfLink":"https://localhost/mgmt/tm/ltm/pool/zf/members/~Common~zf/stats?ver=13.1.0.6","entries":{"activeMemberCnt":{"value":0},"availableMemberCnt":{"value":0},"connqAll.ageEdm":{"value":0},"connqAll.ageEma":{"value":0},"connqAll.ageHead":{"value":0},"connqAll.ageMax":{"value":0},"connqAll.depth":{"value":0},"connqAll.serviced":{"value":0},"connq.ageEdm":{"value":0},"connq.ageEma":{"value":0},"connq.ageHead":{"value":0},"connq.ageMax":{"value":0},"connq.depth":{"value":0},"connq.serviced":{"value":0},"curSessions":{"value":0},"memberCnt":{"value":2},"minActiveMembers":{"value":0},"monitorRule":{"description":"/Common/cn_tomcat"},"tmName":{"description":"/Common/zf"},"serverside.bitsIn":{"value":0},"serverside.bitsOut":{"value":0},"serverside.curConns":{"value":0},"serverside.maxConns":{"value":0},"serverside.pktsIn":{"value":0},"serverside.pktsOut":{"value":0},"serverside.totConns":{"value":0},"status.availabilityState":{"description":"offline"},"status.enabledState":{"description":"enabled"},"status.statusReason":{"description":"The children pool member(s) are down"},"totRequests":{"value":0},"https://localhost/mgmt/tm/ltm/pool/zf/members/~Common~zf/members/stats":{"nestedStats":{"entries":{"https://localhost/mgmt/tm/ltm/pool/zf/members/~Common~zf/members/~Common~192.168.0.16:80/stats":{"nestedStats":{"entries":{"addr":{"description":"192.168.0.16"},"connq.ageEdm":{"value":0},"connq.ageEma":{"value":0},"connq.ageHead":{"value":0},"connq.ageMax":{"value":0},"connq.depth":{"value":0},"connq.serviced":{"value":0},"curSessions":{"value":0},"monitorRule":{"description":"/Common/cn_tomcat (pool monitor)"},"monitorStatus":{"description":"down"},"nodeName":{"description":"/Common/192.168.0.16"},"poolName":{"description":"/Common/zf"},"port":{"value":80},"serverside.bitsIn":{"value":0},"serverside.bitsOut":{"value":0},"serverside.curConns":{"value":0},"serverside.maxConns":{"value":0},"serverside.pktsIn":{"value":0},"serverside.pktsOut":{"value":0},"serverside.totConns":{"value":0},"sessionStatus":{"description":"enabled"},"status.availabilityState":{"description":"offline"},"status.enabledState":{"description":"enabled"},"status.statusReason":{"description":"Pool member has been marked down by a monitor"},"totRequests":{"value":0}}}},"https://localhost/mgmt/tm/ltm/pool/zf/members/~Common~zf/members/~Common~192.168.0.16:8080/stats":{"nestedStats":{"entries":{"addr":{"description":"192.168.0.16"},"connq.ageEdm":{"value":0},"connq.ageEma":{"value":0},"connq.ageHead":{"value":0},"connq.ageMax":{"value":0},"connq.depth":{"value":0},"connq.serviced":{"value":0},"curSessions":{"value":0},"monitorRule":{"description":"/Common/cn_tomcat (pool monitor)"},"monitorStatus":{"description":"user-down"},"nodeName":{"description":"/Common/192.168.0.16"},"poolName":{"description":"/Common/zf"},"port":{"value":8080},"serverside.bitsIn":{"value":0},"serverside.bitsOut":{"value":0},"serverside.curConns":{"value":0},"serverside.maxConns":{"value":0},"serverside.pktsIn":{"value":0},"serverside.pktsOut":{"value":0},"serverside.totConns":{"value":0},"sessionStatus":{"description":"user-disabled"},"status.availabilityState":{"description":"offline"},"status.enabledState":{"description":"disabled"},"status.statusReason":{"description":"Forced down"},"totRequests":{"value":0}}}}}}}}}}}}
If for some reasons the BGIP-IP API returns some malformed cluster sync status, the f5.Client#SyncStatusDetails()
method panics.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.