Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion bigip.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ func NewTokenSession(host, user, passwd, loginProviderName string, configOptions
// APICall is used to query the BIG-IP web API.
func (b *BigIP) APICall(options *APIRequest) ([]byte, error) {
var req *http.Request
if Debug {
fmt.Println()
fmt.Println("API CALL DEBUG Transport:", b.Transport)
fmt.Println("API CALL DEBUG ConfigOptions:", b.ConfigOptions)
fmt.Println()
}
client := &http.Client{
Transport: b.Transport,
Timeout: b.ConfigOptions.APICallTimeout,
Expand All @@ -170,6 +176,14 @@ func (b *BigIP) APICall(options *APIRequest) ([]byte, error) {
req.Header.Set("Content-Type", options.ContentType)
}

if Debug {
fmt.Println()
fmt.Println("DEBUG URL:", url)
fmt.Println("DEBUG BODY:", options.Body)
fmt.Println("DEBUG CONTENT TYPE:", options.ContentType)
fmt.Println()
}

res, err := client.Do(req)
if err != nil {
return nil, err
Expand Down Expand Up @@ -213,11 +227,22 @@ func (b *BigIP) delete(path ...string) error {
}

func (b *BigIP) post(body interface{}, path ...string) error {
if Debug {
fmt.Printf("About to marshal this struct: %+v \r\n", body)
}
marshalJSON, err := jsonMarshal(body)
if err != nil {
return err
}

if Debug {
fmt.Println()
fmt.Println("Request JSON Debug:")
fmt.Println()
fmt.Println(string(marshalJSON))
fmt.Println()
}

req := &APIRequest{
Method: "post",
URL: b.iControlPath(path),
Expand Down Expand Up @@ -256,17 +281,33 @@ func (b *BigIP) getForEntity(e interface{}, path ...string) (error, bool) {
ContentType: "application/json",
}

if Debug {
fmt.Println()
fmt.Printf("REQUEST DEBUG: %+v \r\n", req)
fmt.Println()
}

resp, err := b.APICall(req)
// fmt.Println("DEBUG:" + string(resp))
if err != nil {
var reqError RequestError
json.Unmarshal(resp, &reqError)
if reqError.Code == 404 {
return nil, false
return errors.New("Server returned a 404 for: " + req.URL), false
}
return err, false
}

if Debug {
fmt.Println()
fmt.Println("RESPONSE STRING DEBUG:", string(resp))
fmt.Println()
}

err = json.Unmarshal(resp, e)
if Debug {
fmt.Printf("RESPONSE STRUCT DEBUG: %+v \r\n", e)
}
if err != nil {
return err, false
}
Expand Down Expand Up @@ -302,6 +343,9 @@ func jsonMarshal(t interface{}) ([]byte, error) {
buffer := &bytes.Buffer{}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
if Debug {
fmt.Printf("About to encode %+v \r\n", t)
}
err := encoder.Encode(t)
return buffer.Bytes(), err
}
Expand Down
35 changes: 35 additions & 0 deletions certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package bigip

type SSLCertificateInfo struct {
FileName string `json:"file_name"`
IsBundled bool `json:"is_bundled"`
Certificate struct {
CertInfo struct {
ID string `json:"id"`
Email interface{} `json:"email"`
} `json:"cert_info"`
ExpirationString string `json:"expiration_string"`
CertType string `json:"cert_type"`
KeyType string `json:"key_type"`
Version int `json:"version"`
ExpirationDate int `json:"expiration_date"`
SerialNumber interface{} `json:"serial_number"`
BitLength int `json:"bit_length"`
Issuer struct {
DivisionName string `json:"division_name"`
StateName string `json:"state_name"`
LocalityName string `json:"locality_name"`
OrganizationName string `json:"organization_name"`
CountryName string `json:"country_name"`
CommonName string `json:"common_name"`
} `json:"issuer"`
Subject struct {
DivisionName string `json:"division_name"`
StateName string `json:"state_name"`
LocalityName string `json:"locality_name"`
OrganizationName string `json:"organization_name"`
CountryName string `json:"country_name"`
CommonName string `json:"common_name"`
} `json:"subject"`
} `json:"certificate"`
}
4 changes: 4 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package bigip

// Debug indicates that the program should print verbose debug information
var Debug = false
34 changes: 34 additions & 0 deletions const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package bigip

const (
uriLtm = "ltm"
uriNode = "node"
uriPool = "pool"
uriPoolMember = "members"
uriProfile = "profile"
uriServerSSL = "server-ssl"
uriClientSSL = "client-ssl"
uriProfileHttp = "http"
uriPersistences = "persistences"
uriPersistenceCookie = "cookie"
uriPersistenceSourceAddr = "source-addr"
uriPersistenceHash = "hash"
uriProfileTCP = "tcp"
uriProfileFTP = "ftp"
uriProfileUDP = "udp"
uriProfileFastL4 = "fastl4"
uriOneConnect = "one-connect"
uriVirtual = "virtual"
uriVirtualAddress = "virtual-address"
uriSnatPool = "snatpool"
uriMonitor = "monitor"
uriIRule = "rule"
uriPolicy = "policy"
uriDatagroup = "data-group"
uriInternal = "internal"
ENABLED = "enable"
DISABLED = "disable"
CONTEXT_SERVER = "serverside"
CONTEXT_CLIENT = "clientside"
CONTEXT_ALL = "all"
)
55 changes: 55 additions & 0 deletions dataGroup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package bigip

import "encoding/json"

// DataGroups contains a list of data groups on the BIG-IP system.
type DataGroups struct {
SelfLink string `json:"selfLink,omitempty"`
Kind string `json:"kind,omitempty"`
DataGroups []DataGroup `json:"items,omitempty"`
}

// DataGroups contains information about each data group.
type DataGroup struct {
Kind string `json:"kind,omitempty"`
Name string `json:"name"`
FullPath string `json:"fullPath,omitempty"`
Partition string `json:"tmPartition,omitempty"`
Generation int `json:"generation,omitempty"`
SelfLink string `json:"selfLink,omitempty"`
Type string `json:"type,omitempty"`
Records []DataGroupRecord `json:"records"`
}

type DataGroupRecord struct {
Name string `json:"name"`
Partition string `json:"partition,omitempty"`
SubPath string `json:"subPath,omitempty"`
Data string `json:"data"`
}

type dataGroupDTO struct {
Kind string `json:"kind,omitempty"`
Name string `json:"name,omitempty"`
FullPath string `json:"fullPath,omitempty"`
Partition string `json:"tmPartition,omitempty"`
Generation int `json:"generation,omitempty"`
SelfLink string `json:"selfLink,omitempty"`
Type string `json:"type,omitempty"`
Records []DataGroupRecord `json:"records,omitempty"`
}

func (p *DataGroup) MarshalJSON() ([]byte, error) {
var dto dataGroupDTO
marshal(&dto, p)
return json.Marshal(dto)
}

func (p *DataGroup) UnmarshalJSON(b []byte) error {
var dto dataGroupDTO
err := json.Unmarshal(b, &dto)
if err != nil {
return err
}
return marshal(p, &dto)
}
97 changes: 97 additions & 0 deletions httpProfile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package bigip

type HttpProfiles struct {
HttpProfiles []HttpProfile `json:"items"`
}

type HttpProfile struct {
Kind string `json:"kind,omitempty"`
DefaultsFrom string `json:"defaultsFrom"`
Name string `json:"name"`
Partition string `json:"partition,omitempty"`
FullPath string `json:"fullPath,omitempty"`
Generation int `json:"generation,omitempty"`
SelfLink string `json:"selfLink,omitempty"`
AcceptXff string `json:"acceptXff,omitempty"`
Enforcement struct {
ExcessClientHeaders string `json:"excessClientHeaders,omitempty"`
ExcessServerHeaders string `json:"excessServerHeaders,omitempty"`
MaxHeaderCount int `json:"maxHeaderCount,omitempty"`
MaxHeaderSize int `json:"maxHeaderSize,omitempty"`
MaxRequests int `json:"maxRequests,omitempty"`
OversizeClientHeaders string `json:"oversizeClientHeaders,omitempty"`
OversizeServerHeaders string `json:"oversizeServerHeaders,omitempty"`
Pipeline string `json:"pipeline,omitempty"`
TruncatedRedirects string `json:"truncatedRedirects,omitempty"`
UnknownMethod string `json:"unknownMethod,omitempty"`
} `json:"enforcement,omitempty"`
ExplicitProxy struct {
DefaultConnectHandling string `json:"defaultConnectHandling,omitempty"`
} `json:"explicitProxy,omitempty"`
InsertXforwardedFor string `json:"insertXforwardedFor,omitempty"`
LwsWidth int `json:"lwsWidth,omitempty"`
OneconnectTransformations string `json:"oneconnectTransformations,omitempty"`
ProxyType string `json:"proxyType,omitempty"`
RequestChunking string `json:"requestChunking,omitempty"`
ResponseChunking string `json:"responseChunking,omitempty"`
ServerAgentName string `json:"serverAgentName,omitempty"`
Sflow struct {
PollInterval int `json:"pollInterval,omitempty"`
PollIntervalGlobal string `json:"pollIntervalGlobal,omitempty"`
SamplingRate int `json:"samplingRate,omitempty"`
SamplingRateGlobal string `json:"samplingRateGlobal,omitempty"`
} `json:"sflow,omitempty"`
ViaRequest string `json:"viaRequest,omitempty"`
ViaResponse string `json:"viaResponse,omitempty"`
}

// HttpProfiles returns a list of http profiles.
func (b *BigIP) HttpProfiles() (*HttpProfiles, error) {
var httpProfiles HttpProfiles
err, _ := b.getForEntity(&httpProfiles, uriLtm, uriProfile, uriProfileHttp)
if err != nil {
return nil, err
}

return &httpProfiles, nil
}

// GetHttpProfile gets a http profile by name. Returns nil if the http profile does not exist
func (b *BigIP) GetHttpProfile(name string) (*HttpProfile, error) {
var httpProfile HttpProfile
err, ok := b.getForEntity(&httpProfile, uriLtm, uriProfile, uriProfileHttp, name)
if err != nil {
return nil, err
}
if !ok {
return nil, nil
}

return &httpProfile, nil
}

// CreateHttpProfile creates a new http profile on the BIG-IP system.
func (b *BigIP) CreateHttpProfile(name string, parent string) error {
config := &HttpProfile{
Name: name,
DefaultsFrom: parent,
}

return b.post(config, uriLtm, uriProfile, uriProfileHttp)
}

// AddHttpProfile adds a new http profile on the BIG-IP system.
func (b *BigIP) AddHttpProfile(config *HttpProfile) error {
return b.post(config, uriLtm, uriProfile, uriProfileHttp)
}

// DeleteHttpProfile removes a http profile.
func (b *BigIP) DeleteHttpProfile(name string) error {
return b.delete(uriLtm, uriProfile, uriProfileHttp, name)
}

// ModifyHttpProfile allows you to change any attribute of a http profile.
// Fields that can be modified are referenced in the HttpProfile struct.
func (b *BigIP) ModifyHttpProfile(name string, config *HttpProfile) error {
return b.put(config, uriLtm, uriProfile, uriProfileHttp, name)
}
56 changes: 56 additions & 0 deletions iRule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package bigip

// IRules returns a list of irules
func (b *BigIP) IRules() (*IRules, error) {
var rules IRules
err, _ := b.getForEntity(&rules, uriLtm, uriIRule)
if err != nil {
return nil, err
}

return &rules, nil
}

// IRule returns information about the given iRule.
func (b *BigIP) IRule(name string) (*IRule, error) {
var rule IRule
err, ok := b.getForEntity(&rule, uriLtm, uriIRule, name)
if err != nil {
return nil, err
}
if !ok {
return nil, nil
}
return &rule, nil
}

// CreateIRule creates a new iRule on the system.
func (b *BigIP) CreateIRule(name, rule string) error {
irule := &IRule{
Name: name,
Rule: rule,
}
return b.post(irule, uriLtm, uriIRule)
}

// DeleteIRule removes an iRule from the system.
func (b *BigIP) DeleteIRule(name string) error {
return b.delete(uriLtm, uriIRule, name)
}

// ModifyIRule updates the given iRule with any changed values.
func (b *BigIP) ModifyIRule(name string, irule *IRule) error {
irule.Name = name
return b.put(irule, uriLtm, uriIRule, name)
}

type IRules struct {
IRules []IRule `json:"items"`
}

type IRule struct {
Name string `json:"name,omitempty"`
Partition string `json:"partition,omitempty"`
FullPath string `json:"fullPath,omitempty"`
Rule string `json:"apiAnonymous,omitempty"`
}
Loading