From 46eb076a3973274b59d2babd0915a85cbbb16504 Mon Sep 17 00:00:00 2001 From: Tamara Vassileva Date: Wed, 1 Nov 2023 18:56:17 +1100 Subject: [PATCH 1/3] bubble out configOptions as provider options --- bigip/provider.go | 26 ++++++++++++++++++++++++++ docs/index.md | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/bigip/provider.go b/bigip/provider.go index d49ea16a3..314d36a54 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -14,6 +14,7 @@ import ( "reflect" "regexp" "strings" + "time" bigip "github.com/f5devcentral/go-bigip" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -85,6 +86,24 @@ func Provider() *schema.Provider { Description: "Login reference for token authentication (see BIG-IP REST docs for details)", DefaultFunc: schema.EnvDefaultFunc("BIGIP_LOGIN_REF", "tmos"), }, + "api_timeout": { + Type: schema.TypeInt, + Optional: true, + Description: "A timeout for AS3 requests, represented as a number of seconds. Default: 60", + DefaultFunc: schema.EnvDefaultFunc("API_TIMEOUT", 60), + }, + "token_timeout": { + Type: schema.TypeInt, + Optional: true, + Description: "A lifespan to request for the AS3 auth token, represented as a number of seconds. Default: 1200", + DefaultFunc: schema.EnvDefaultFunc("TOKEN_TIMEOUT", 1200), + }, + "api_retries": { + Type: schema.TypeInt, + Optional: true, + Description: "Amount of times to retry AS3 API requests. Default: 10.", + DefaultFunc: schema.EnvDefaultFunc("API_TIMEOUT", 10), + }, }, DataSourcesMap: map[string]*schema.Resource{ "bigip_ltm_datagroup": dataSourceBigipLtmDataGroup(), @@ -183,6 +202,12 @@ func Provider() *schema.Provider { } func providerConfigure(d *schema.ResourceData, terraformVersion string) (interface{}, diag.Diagnostics) { + configOptions := &bigip.ConfigOptions{ + APICallTimeout: (d.Get("api_timeout").(time.Duration) * time.Second), + TokenTimeout: (d.Get("token_timeout").(time.Duration) * time.Second), + APICallRetries: d.Get("api_retries").(int), + } + config := &bigip.Config{ Address: d.Get("address").(string), Port: d.Get("port").(string), @@ -190,6 +215,7 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa Password: d.Get("password").(string), Token: d.Get("token_value").(string), CertVerifyDisable: d.Get("validate_certs_disable").(bool), + ConfigOptions: configOptions, } if d.Get("token_auth").(bool) { config.LoginReference = d.Get("login_ref").(string) diff --git a/docs/index.md b/docs/index.md index 5011c674a..f79b8b5ad 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,6 +17,7 @@ This provider uses the iControlREST API. All the resources are validated with Bi ~> **NOTE** For AWAF resources, F5 BIG-IP version should be > v16.x , and ASM need to be provisioned. ## Example Usage + ```hcl variable hostname {} variable username {} @@ -45,6 +46,9 @@ provider "bigip" { - `password` - (type `string`) BIG-IP Password for authentication. Can be set via the `BIGIP_PASSWORD` environment variable. - `token_auth` - (Optional, Default `true`) Enable to use token authentication. Can be set via the `BIGIP_TOKEN_AUTH` environment variable. - `token_value` - (Optional) A token generated outside the provider, in place of password +- `api_timeout` - (Optional, type `int`) A timeout for AS3 requests, represented as a number of seconds. +- `token_timeout` - (Optional, type `int`) A lifespan to request for the AS3 auth token, represented as a number of seconds. +- `api_retries` - (Optional, type `int`) Amount of times to retry AS3 API requests. - `login_ref` - (Optional,Default `tmos`) Login reference for token authentication (see BIG-IP REST docs for details). May be set via the `BIGIP_LOGIN_REF` environment variable. - `port` - (Optional) Management Port to connect to BIG-IP,this is mainly required if we have single nic BIG-IP in AWS/Azure/GCP (or) Management port other than `443`. Can be set via `BIGIP_PORT` environment variable. - `validate_certs_disable` - (Optional, Default `true`) If set to true, Disables TLS certificate check on BIG-IP. Can be set via the `BIGIP_VERIFY_CERT_DISABLE` environment variable. From f196c5325e4b5bfe686122080026cbb89f55af2e Mon Sep 17 00:00:00 2001 From: Tamara Vassileva Date: Thu, 2 Nov 2023 15:23:45 +1100 Subject: [PATCH 2/3] fix a typo in the schema --- bigip/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bigip/provider.go b/bigip/provider.go index 314d36a54..60b7ac2e2 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -102,7 +102,7 @@ func Provider() *schema.Provider { Type: schema.TypeInt, Optional: true, Description: "Amount of times to retry AS3 API requests. Default: 10.", - DefaultFunc: schema.EnvDefaultFunc("API_TIMEOUT", 10), + DefaultFunc: schema.EnvDefaultFunc("API_RETRIES", 10), }, }, DataSourcesMap: map[string]*schema.Resource{ From f7d57e54992ec9d8e854ce15cb4d3597267f3c98 Mon Sep 17 00:00:00 2001 From: Tamara Vassileva Date: Tue, 14 Nov 2023 14:37:26 +1100 Subject: [PATCH 3/3] add logic to actually update token lifespan and API timeout --- .../github.com/f5devcentral/go-bigip/bigip.go | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/vendor/github.com/f5devcentral/go-bigip/bigip.go b/vendor/github.com/f5devcentral/go-bigip/bigip.go index 5b1d22c1e..eb4c1d629 100644 --- a/vendor/github.com/f5devcentral/go-bigip/bigip.go +++ b/vendor/github.com/f5devcentral/go-bigip/bigip.go @@ -144,6 +144,19 @@ func NewTokenSession(bigipConfig *Config) (b *BigIP, err error) { Token struct { Token string } + Timeout struct { + Timeout int64 + } + } + + type timeoutReq struct { + Timeout int64 `json:"timeout"` + } + + type timeoutResp struct { + Timeout struct { + Timeout int64 + } } auth := authReq{ @@ -152,7 +165,7 @@ func NewTokenSession(bigipConfig *Config) (b *BigIP, err error) { bigipConfig.LoginReference, } - marshalJSON, err := json.Marshal(auth) + marshalJSONauth, err := json.Marshal(auth) if err != nil { return } @@ -160,7 +173,7 @@ func NewTokenSession(bigipConfig *Config) (b *BigIP, err error) { req := &APIRequest{ Method: "post", URL: "mgmt/shared/authn/login", - Body: string(marshalJSON), + Body: string(marshalJSONauth), ContentType: "application/json", } @@ -207,6 +220,46 @@ func NewTokenSession(bigipConfig *Config) (b *BigIP, err error) { b.Token = aresp.Token.Token + //Once we have obtained a token, we should actually apply the configured timeout to it + if time.Duration(aresp.Timeout.Timeout)*time.Second != bigipConfig.ConfigOptions.TokenTimeout { // The inital value is the max timespan + timeout := timeoutReq{ + int64(bigipConfig.ConfigOptions.TokenTimeout.Seconds()), + } + + marshalJSONtimeout, errToken := json.Marshal(timeout) + if errToken != nil { + return b, errToken + } + + timeoutReq := &APIRequest{ + Method: "patch", + URL: ("mgmt/shared/authz/tokens/" + b.Token), + Body: string(marshalJSONtimeout), + ContentType: "application/json", + } + + resp, errToken := b.APICall(timeoutReq) + if errToken != nil { + return b, errToken + } + + if resp == nil { + errToken = fmt.Errorf("unable to update token timeout") + return b, errToken + } + + var tresp timeoutResp + errToken = json.Unmarshal(resp, &tresp) + if err != nil { + return b, errToken + } + + if time.Duration(tresp.Timeout.Timeout)*time.Second != bigipConfig.ConfigOptions.TokenTimeout { + err = fmt.Errorf("failed to update token lifespan") + return + } + + } return }