From 2c7242326ac9f9a115706651e76c5e7f134d2c87 Mon Sep 17 00:00:00 2001 From: chinthalapalli Date: Tue, 3 Oct 2023 14:57:41 +0530 Subject: [PATCH 01/10] adding cipher rule/group support for profiles --- bigip/resource_bigip_ltm_cipher_rule.go | 7 ++++--- bigip/resource_bigip_ltm_profile_ssl_client.go | 4 ++-- bigip/resource_bigip_ltm_profile_ssl_server.go | 12 ++++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bigip/resource_bigip_ltm_cipher_rule.go b/bigip/resource_bigip_ltm_cipher_rule.go index dfd48f578..bc658713f 100644 --- a/bigip/resource_bigip_ltm_cipher_rule.go +++ b/bigip/resource_bigip_ltm_cipher_rule.go @@ -48,11 +48,13 @@ func resourceBigipLtmCipherRule() *schema.Resource { "dh_groups": { Type: schema.TypeString, Optional: true, + Computed: true, Description: "Specifies the DH Groups Elliptic Curve Diffie-Hellman key exchange algorithms, separated by colons (:).Note: You can also type a special keyword, DEFAULT, which represents the recommended set of named groups", }, "signature_algorithms": { Type: schema.TypeString, Optional: true, + Computed: true, Description: "Specifies the Signature Algorithms, separated by colons (:), that you want to include in the cipher rule. You can also type a special keyword, DEFAULT, which represents the recommended set of signature algorithms", }, }, @@ -108,9 +110,8 @@ func resourceBigipLtmCipherRuleRead(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } log.Printf("[INFO] Cipher rule response :%+v", cipherRule) - _ = d.Set("name", cipherRule.Name) - _ = d.Set("partition", cipherRule.Partition) - _ = d.Set("cipher_suites", cipherRule.Cipher) + _ = d.Set("name", cipherRule.FullPath) + _ = d.Set("cipher", cipherRule.Cipher) _ = d.Set("dh_groups", cipherRule.DhGroups) _ = d.Set("signature_algorithms", cipherRule.SignatureAlgorithms) return nil diff --git a/bigip/resource_bigip_ltm_profile_ssl_client.go b/bigip/resource_bigip_ltm_profile_ssl_client.go index 8c643bf1b..c8bc835cf 100644 --- a/bigip/resource_bigip_ltm_profile_ssl_client.go +++ b/bigip/resource_bigip_ltm_profile_ssl_client.go @@ -873,8 +873,8 @@ func getClientSslConfig(d *schema.ResourceData, config *bigip.ClientSSLProfile) config.Ciphers = ciphers.(string) config.CipherGroup = "none" } - if cipher_grp, ok := d.GetOk("cipher_group"); ok && cipher_grp != "none" { - config.CipherGroup = cipher_grp.(string) + if cipherGrp, ok := d.GetOk("cipher_group"); ok && cipherGrp != "none" { + config.CipherGroup = cipherGrp.(string) config.Ciphers = "none" } config.ClientCertCa = d.Get("client_cert_ca").(string) diff --git a/bigip/resource_bigip_ltm_profile_ssl_server.go b/bigip/resource_bigip_ltm_profile_ssl_server.go index 94b19e990..3a0006162 100644 --- a/bigip/resource_bigip_ltm_profile_ssl_server.go +++ b/bigip/resource_bigip_ltm_profile_ssl_server.go @@ -493,8 +493,12 @@ func resourceBigipLtmProfileServerSslRead(ctx context.Context, d *schema.Resourc _ = d.Set("ca_file", obj.CaFile) _ = d.Set("cert", obj.Cert) _ = d.Set("chain", obj.Chain) - _ = d.Set("ciphers", obj.Ciphers) - _ = d.Set("cipher_group", obj.CipherGroup) + if _, ok := d.GetOk("ciphers"); ok { + _ = d.Set("ciphers", obj.Ciphers) + } + if _, ok := d.GetOk("cipher_group"); ok { + _ = d.Set("cipher_group", obj.CipherGroup) + } _ = d.Set("expire_cert_response_control", obj.ExpireCertResponseControl) _ = d.Set("cache_size", obj.CacheSize) _ = d.Set("handshake_timeout", obj.HandshakeTimeout) @@ -637,8 +641,8 @@ func getServerSslConfig(d *schema.ResourceData, config *bigip.ServerSSLProfile) config.Ciphers = ciphers.(string) config.CipherGroup = "none" } - if cipher_grp, ok := d.GetOk("cipher_group"); ok && cipher_grp != "none" { - config.CipherGroup = cipher_grp.(string) + if cipherGrp, ok := d.GetOk("cipher_group"); ok && cipherGrp != "none" { + config.CipherGroup = cipherGrp.(string) config.Ciphers = "none" } config.ExpireCertResponseControl = d.Get("expire_cert_response_control").(string) From f00bc353d8d87a3575dc41e2966db9a99a393c2a Mon Sep 17 00:00:00 2001 From: chinthalapalli Date: Wed, 4 Oct 2023 19:05:11 +0530 Subject: [PATCH 02/10] adding fix for cipher group read parameter --- bigip/resource_bigip_ltm_cipher_group.go | 13 ++++++++++++- docs/index.md | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bigip/resource_bigip_ltm_cipher_group.go b/bigip/resource_bigip_ltm_cipher_group.go index 1ff7ca430..c2288541f 100644 --- a/bigip/resource_bigip_ltm_cipher_group.go +++ b/bigip/resource_bigip_ltm_cipher_group.go @@ -113,7 +113,18 @@ func resourceBigipLtmCipherGroupRead(ctx context.Context, d *schema.ResourceData } _ = d.Set("name", cipherGroup.FullPath) _ = d.Set("ordering", cipherGroup.Ordering) - log.Printf("[INFO] Cipher group response :%+v", cipherGroup) + var allowList []interface{} + for _, val := range cipherGroup.Allow { + tmpCipher := fmt.Sprintf("/%s/%s", val.(map[string]interface{})["partition"].(string), val.(map[string]interface{})["name"].(string)) + allowList = append(allowList, tmpCipher) + } + _ = d.Set("allow", allowList) + var requireList []interface{} + for _, val := range cipherGroup.Require { + tmpCipher := fmt.Sprintf("/%s/%s", val.(map[string]interface{})["partition"].(string), val.(map[string]interface{})["name"].(string)) + requireList = append(requireList, tmpCipher) + } + _ = d.Set("require", requireList) return nil } diff --git a/docs/index.md b/docs/index.md index f8f7ef677..5011c674a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -43,7 +43,7 @@ provider "bigip" { - `address` - (type `string`) Domain name or IP address of the BIG-IP. Can be set via the `BIGIP_HOST` environment variable. - `username` - (type `string`) BIG-IP Username for authentication. Can be set via the `BIGIP_USER` environment variable. - `password` - (type `string`) BIG-IP Password for authentication. Can be set via the `BIGIP_PASSWORD` environment variable. -- `token_auth` - (Optional, Default `false`) Enable to use an external authentication source (LDAP, TACACS, etc). Can be set via the `BIGIP_TOKEN_AUTH` 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 - `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. From 1d2dcaa4b14caeba3605d7780a05bb9eeb164a0d Mon Sep 17 00:00:00 2001 From: ramaniprateek Date: Thu, 5 Oct 2023 11:34:48 +0530 Subject: [PATCH 03/10] Issues-Ltm Profile Fixed and Documented --- bigip/resource_bigip_ltm_profile_http.go | 133 +++++++++++++++++- docs/resources/bigip_ltm_profile_http.md | 31 ++++ .../github.com/f5devcentral/go-bigip/ltm.go | 23 +++ 3 files changed, 184 insertions(+), 3 deletions(-) diff --git a/bigip/resource_bigip_ltm_profile_http.go b/bigip/resource_bigip_ltm_profile_http.go index 092a892ac..8c8ae4f18 100644 --- a/bigip/resource_bigip_ltm_profile_http.go +++ b/bigip/resource_bigip_ltm_profile_http.go @@ -166,9 +166,10 @@ func resourceBigipLtmProfileHttp() *schema.Resource { Description: "Specifies how the system handles HTTP content that is chunked by a server. The default is Selective", }, "server_agent_name": { - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + // Computed: true, + Default: "BigIP", Description: "Specifies the value of the Server header in responses that the BIG-IP itself generates. The default is BigIP. If no string is specified, then no Server header will be added to such responses", }, "via_host_name": { @@ -197,6 +198,72 @@ func resourceBigipLtmProfileHttp() *schema.Resource { Computed: true, Description: "Specifies alternative XFF headers instead of the default X-forwarded-for header", }, + "http_strict_transport_security": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "include_subdomains": { + Type: schema.TypeString, + Optional: true, + Default: "enabled", + Description: "Specifies whether to include the includeSubdomains directive in the HSTS header.", + }, + "maximum_age": { + Type: schema.TypeInt, + Optional: true, + Default: 16070400, + Description: "Specifies the maximum age to assume the connection should remain secure.", + }, + "mode": { + Type: schema.TypeString, + Optional: true, + Default: "disabled", + Description: "Specifies whether to include the HSTS response header.", + }, + "preload": { + Type: schema.TypeString, + Optional: true, + Default: "disabled", + Description: "Specifies whether to include the preload directive in the HSTS header.", + }, + }, + }, + }, + "enforcement": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "known_methods": { + Type: schema.TypeSet, + Set: schema.HashString, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Description: "Specifies which HTTP methods count as being known. Removing RFC-defined methods from this list will cause the HTTP filter to not recognize them.", + }, + "max_header_count": { + Type: schema.TypeInt, + Optional: true, + Default: 64, + Description: "Specifies the maximum number of headers allowed in HTTP request/response.", + }, + "max_header_size": { + Type: schema.TypeInt, + Optional: true, + Default: 32768, + Description: "Specifies the maximum header size.", + }, + "unknown_method": { + Type: schema.TypeString, + Optional: true, + Default: "allow", + Description: "Specifies whether to allow, reject or switch to pass-through mode when an unknown HTTP method is parsed.", + }, + }, + }, + }, }, } } @@ -212,6 +279,15 @@ func resourceBigipLtmProfileHttpCreate(ctx context.Context, d *schema.ResourceDa } config := getHttpProfileConfig(d, pss) + if p, ok := d.GetOk("enforcement"); ok { + for _, r := range p.(*schema.Set).List() { + if len(r.(map[string]interface{})["known_methods"].(*schema.Set).List()) == 0 { + defaultKnownMethods := [...]string{"CONNECT", "DELETE", "GET", "HEAD", "LOCK", "OPTIONS", "POST", "PROPFIND", "PUT", "TRACE", "UNLOCK"} + config.Enforcement.KnownMethods = defaultKnownMethods[:] + } + } + } + err := client.AddHttpProfile(config) if err != nil { return diag.FromErr(err) @@ -325,6 +401,28 @@ func resourceBigipLtmProfileHttpRead(ctx context.Context, d *schema.ResourceData } _ = d.Set("xff_alternative_names", pp.XffAlternativeNames) + log.Printf("Known Methods--------", pp.Enforcement.KnownMethods) + + var enforcementList []interface{} + enforcement := make(map[string]interface{}) + enforcement["max_header_count"] = pp.Enforcement.MaxHeaderCount + enforcement["max_header_size"] = pp.Enforcement.MaxHeaderSize + enforcement["unknown_method"] = pp.Enforcement.UnknownMethod + enforcement["known_methods"] = pp.Enforcement.KnownMethods + + enforcementList = append(enforcementList, enforcement) + _ = d.Set("enforcement", enforcementList) + + var hstsList []interface{} + hsts := make(map[string]interface{}) + hsts["include_subdomains"] = pp.Hsts.IncludeSubdomains + hsts["maximum_age"] = pp.Hsts.MaximumAge + hsts["mode"] = pp.Hsts.Mode + hsts["preload"] = pp.Hsts.Preload + + hstsList = append(hstsList, hsts) + _ = d.Set("http_strict_transport_security", hstsList) + return nil } @@ -337,6 +435,16 @@ func resourceBigipLtmProfileHttpUpdate(ctx context.Context, d *schema.ResourceDa Name: name, } config := getHttpProfileConfig(d, pss) + + if p, ok := d.GetOk("enforcement"); ok { + for _, r := range p.(*schema.Set).List() { + if len(r.(map[string]interface{})["known_methods"].(*schema.Set).List()) == 0 { + defaultKnownMethods := [...]string{"CONNECT", "DELETE", "GET", "HEAD", "LOCK", "OPTIONS", "POST", "PROPFIND", "PUT", "TRACE", "UNLOCK"} + config.Enforcement.KnownMethods = defaultKnownMethods[:] + } + } + } + err := client.ModifyHttpProfile(name, config) if err != nil { @@ -387,5 +495,24 @@ func getHttpProfileConfig(d *schema.ResourceData, config *bigip.HttpProfile) *bi config.ViaRequest = d.Get("via_request").(string) config.ViaResponse = d.Get("via_response").(string) config.XffAlternativeNames = setToInterfaceSlice(d.Get("xff_alternative_names").(*schema.Set)) + config.LwsWidth = d.Get("lws_width").(int) + if p, ok := d.GetOk("http_strict_transport_security"); ok { + for _, r := range p.(*schema.Set).List() { + config.Hsts.IncludeSubdomains = r.(map[string]interface{})["include_subdomains"].(string) + config.Hsts.Mode = r.(map[string]interface{})["preload"].(string) + config.Hsts.Preload = r.(map[string]interface{})["mode"].(string) + config.Hsts.MaximumAge = r.(map[string]interface{})["maximum_age"].(int) + } + } + + if p, ok := d.GetOk("enforcement"); ok { + for _, r := range p.(*schema.Set).List() { + config.Enforcement.KnownMethods = setToStringSlice(r.(map[string]interface{})["known_methods"].(*schema.Set)) + config.Enforcement.UnknownMethod = r.(map[string]interface{})["unknown_method"].(string) + config.Enforcement.MaxHeaderCount = r.(map[string]interface{})["max_header_count"].(int) + config.Enforcement.MaxHeaderSize = r.(map[string]interface{})["max_header_size"].(int) + } + } + return config } diff --git a/docs/resources/bigip_ltm_profile_http.md b/docs/resources/bigip_ltm_profile_http.md index 7efbe1758..bbe46efed 100644 --- a/docs/resources/bigip_ltm_profile_http.md +++ b/docs/resources/bigip_ltm_profile_http.md @@ -73,6 +73,37 @@ resource "bigip_ltm_profile_http" "sanjose-http" { * `xff_alternative_names` - (Optional) Specifies alternative XFF headers instead of the default X-forwarded-for header. +* `server_agent_name` - (Optional) Specifies the value of the Server header in responses that the BIG-IP itself generates. The default is BigIP. If no string is specified, then default value will be added to such responses. In order to remove it, "none" string is to be passed. + +* `enforcement` -See [Enforcement](#enforcement) below for more details. + +* `http_strict_transport_security` -See [Http_Strict_Transport_Security](#http_strict_transport_security) below for more details. + +### Enforcement + +The `enforcement` block supports the following: + +* `known_methods` - (Optional , `list`) Specifies which HTTP methods count as being known. Removing RFC-defined methods from this list will cause the HTTP filter to not recognize them. Default value is [CONNECT DELETE GET HEAD LOCK OPTIONS POST PROPFIND PUT TRACE UNLOCK]. If no value is specified, then default value will be added to such responses. In order to remove it, [""] list is to be passed. + +* `unknown_method` - (Optional , `string`) Specifies whether to allow, reject or switch to pass-through mode when an unknown HTTP method is parsed. Default value is allow. If no string is specified, then default value will be assigned. + +* `max_header_count` - (Optional , `int`) Specifies the maximum number of headers allowed in HTTP request/response. The default is 64 headers.If no value is specified, then default value will be assigned. + +* `max_header_size` - (Optional , `int`) Specifies the maximum header size.The default value is 32768.If no string is specified, then default value will be assigned. + + +### Http_Strict_Transport_Security + +The `http_strict_transport_security` block supports the following: + +* `include_subdomains` - (Optional , `string`) Specifies whether to include the includeSubdomains directive in the HSTS header. The default is enabled. If no string is specified, then default value will be assigned. + +* `preload` - (Optional , `string`) Specifies whether to include the preload directive in the HSTS header. The default is disabled. If no string is specified, then default value will be assigned. + +* `mode` - (Optional , `string`) Specifies whether to include the HSTS response header. The default is disabled.If no string is specified, then default value will be assigned. + +* `maximum_age` - (Optional , `int`) Specifies the maximum age to assume the connection should remain secure. The default is 16070400 seconds. If no value is specified, then default value will be assigned. + ## Import diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index 4e57c326f..c8d675d27 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -1835,6 +1835,29 @@ type HttpProfile struct { ViaRequest string `json:"viaRequest,omitempty"` ViaResponse string `json:"viaResponse,omitempty"` XffAlternativeNames []interface{} `json:"xffAlternativeNames,omitempty"` + Hsts HTTPStrictTransportSecurity `json:"hsts,omitempty"` + Enforcement Enforcement `json:"enforcement,omitempty"` +} + +type HTTPStrictTransportSecurity struct { + IncludeSubdomains string `json:"includeSubdomains,omitempty"` + MaximumAge int `json:"maximumAge,omitempty"` + Mode string `json:"mode,omitempty"` + Preload string `json:"preload,omitempty"` +} + +type Enforcement struct { + KnownMethods []string `json:"knownMethods,omitempty"` + ExcessClientHeaders string + ExcessServerHeaders string + MaxHeaderCount int `json:"maxHeaderCount,omitempty"` + MaxHeaderSize int `json:"maxHeaderSize,omitempty"` + MaxRequests int + OversizeClientHeaders string + OversizeServerHeaders string + Pipeline string + TruncatedRedirects string + UnknownMethod string `json:"unknownMethod,omitempty"` } type OneconnectProfiles struct { From ae2c2f6ad126c7e2a5097f75fc2e58abda95e0f4 Mon Sep 17 00:00:00 2001 From: ramaniprateek Date: Fri, 6 Oct 2023 15:47:43 +0530 Subject: [PATCH 04/10] Known Method Issue Fixed , Removed Logs , Changed Documentation, Tests Added --- bigip/resource_bigip_ltm_profile_http.go | 79 ++++++++------- bigip/resource_bigip_ltm_profile_http_test.go | 97 +++++++++++++++++++ docs/resources/bigip_ltm_profile_http.md | 2 +- 3 files changed, 136 insertions(+), 42 deletions(-) diff --git a/bigip/resource_bigip_ltm_profile_http.go b/bigip/resource_bigip_ltm_profile_http.go index 8c8ae4f18..3cc8c65c5 100644 --- a/bigip/resource_bigip_ltm_profile_http.go +++ b/bigip/resource_bigip_ltm_profile_http.go @@ -233,13 +233,13 @@ func resourceBigipLtmProfileHttp() *schema.Resource { "enforcement": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "known_methods": { - Type: schema.TypeSet, - Set: schema.HashString, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, Optional: true, Description: "Specifies which HTTP methods count as being known. Removing RFC-defined methods from this list will cause the HTTP filter to not recognize them.", }, @@ -272,21 +272,12 @@ func resourceBigipLtmProfileHttpCreate(ctx context.Context, d *schema.ResourceDa client := meta.(*bigip.BigIP) name := d.Get("name").(string) - log.Printf("[INFO] Creating HTTP Profile:%+v ", name) pss := &bigip.HttpProfile{ Name: name, } config := getHttpProfileConfig(d, pss) - if p, ok := d.GetOk("enforcement"); ok { - for _, r := range p.(*schema.Set).List() { - if len(r.(map[string]interface{})["known_methods"].(*schema.Set).List()) == 0 { - defaultKnownMethods := [...]string{"CONNECT", "DELETE", "GET", "HEAD", "LOCK", "OPTIONS", "POST", "PROPFIND", "PUT", "TRACE", "UNLOCK"} - config.Enforcement.KnownMethods = defaultKnownMethods[:] - } - } - } err := client.AddHttpProfile(config) if err != nil { @@ -401,18 +392,27 @@ func resourceBigipLtmProfileHttpRead(ctx context.Context, d *schema.ResourceData } _ = d.Set("xff_alternative_names", pp.XffAlternativeNames) - log.Printf("Known Methods--------", pp.Enforcement.KnownMethods) var enforcementList []interface{} enforcement := make(map[string]interface{}) enforcement["max_header_count"] = pp.Enforcement.MaxHeaderCount enforcement["max_header_size"] = pp.Enforcement.MaxHeaderSize enforcement["unknown_method"] = pp.Enforcement.UnknownMethod - enforcement["known_methods"] = pp.Enforcement.KnownMethods + + if p, ok := d.GetOk("enforcement"); ok { + for _, r := range p.(*schema.Set).List() { + if len(r.(map[string]interface{})["known_methods"].([]interface{})) != 0 { + enforcement["known_methods"] = pp.Enforcement.KnownMethods + } + } + } enforcementList = append(enforcementList, enforcement) - _ = d.Set("enforcement", enforcementList) - + + if _, ok := d.GetOk("enforcement"); ok { + _ = d.Set("enforcement", enforcementList) + } + var hstsList []interface{} hsts := make(map[string]interface{}) hsts["include_subdomains"] = pp.Hsts.IncludeSubdomains @@ -421,8 +421,9 @@ func resourceBigipLtmProfileHttpRead(ctx context.Context, d *schema.ResourceData hsts["preload"] = pp.Hsts.Preload hstsList = append(hstsList, hsts) - _ = d.Set("http_strict_transport_security", hstsList) - + if _, ok := d.GetOk("http_strict_transport_security"); ok { + _ = d.Set("http_strict_transport_security", hstsList) + } return nil } @@ -436,15 +437,6 @@ func resourceBigipLtmProfileHttpUpdate(ctx context.Context, d *schema.ResourceDa } config := getHttpProfileConfig(d, pss) - if p, ok := d.GetOk("enforcement"); ok { - for _, r := range p.(*schema.Set).List() { - if len(r.(map[string]interface{})["known_methods"].(*schema.Set).List()) == 0 { - defaultKnownMethods := [...]string{"CONNECT", "DELETE", "GET", "HEAD", "LOCK", "OPTIONS", "POST", "PROPFIND", "PUT", "TRACE", "UNLOCK"} - config.Enforcement.KnownMethods = defaultKnownMethods[:] - } - } - } - err := client.ModifyHttpProfile(name, config) if err != nil { @@ -496,22 +488,27 @@ func getHttpProfileConfig(d *schema.ResourceData, config *bigip.HttpProfile) *bi config.ViaResponse = d.Get("via_response").(string) config.XffAlternativeNames = setToInterfaceSlice(d.Get("xff_alternative_names").(*schema.Set)) config.LwsWidth = d.Get("lws_width").(int) - if p, ok := d.GetOk("http_strict_transport_security"); ok { - for _, r := range p.(*schema.Set).List() { - config.Hsts.IncludeSubdomains = r.(map[string]interface{})["include_subdomains"].(string) - config.Hsts.Mode = r.(map[string]interface{})["preload"].(string) - config.Hsts.Preload = r.(map[string]interface{})["mode"].(string) - config.Hsts.MaximumAge = r.(map[string]interface{})["maximum_age"].(int) - } + p := d.Get("http_strict_transport_security") + + for _, r := range p.(*schema.Set).List() { + config.Hsts.IncludeSubdomains = r.(map[string]interface{})["include_subdomains"].(string) + config.Hsts.Mode = r.(map[string]interface{})["preload"].(string) + config.Hsts.Preload = r.(map[string]interface{})["mode"].(string) + config.Hsts.MaximumAge = r.(map[string]interface{})["maximum_age"].(int) } - if p, ok := d.GetOk("enforcement"); ok { - for _, r := range p.(*schema.Set).List() { - config.Enforcement.KnownMethods = setToStringSlice(r.(map[string]interface{})["known_methods"].(*schema.Set)) - config.Enforcement.UnknownMethod = r.(map[string]interface{})["unknown_method"].(string) - config.Enforcement.MaxHeaderCount = r.(map[string]interface{})["max_header_count"].(int) - config.Enforcement.MaxHeaderSize = r.(map[string]interface{})["max_header_size"].(int) + + v := d.Get("enforcement") + + for _, r := range v.(*schema.Set).List() { + var knownMethods []string + for _, val := range r.(map[string]interface{})["known_methods"].([]interface{}) { + knownMethods = append(knownMethods, val.(string)) } + config.Enforcement.KnownMethods = knownMethods + config.Enforcement.UnknownMethod = r.(map[string]interface{})["unknown_method"].(string) + config.Enforcement.MaxHeaderCount = r.(map[string]interface{})["max_header_count"].(int) + config.Enforcement.MaxHeaderSize = r.(map[string]interface{})["max_header_size"].(int) } return config diff --git a/bigip/resource_bigip_ltm_profile_http_test.go b/bigip/resource_bigip_ltm_profile_http_test.go index 09533b517..5f3c30ed8 100644 --- a/bigip/resource_bigip_ltm_profile_http_test.go +++ b/bigip/resource_bigip_ltm_profile_http_test.go @@ -342,6 +342,87 @@ func TestAccBigipLtmProfileHttpUpdateEncryptCookies(t *testing.T) { }) } +func TestAccBigipLtmProfileHttpUpdateEnforcement(t *testing.T) { + t.Parallel() + var instName = "test-http-Update-enforcement" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resHttpName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckHttpsDestroyed, + Steps: []resource.TestStep{ + { + Config: testaccbigipltmprofilehttpUpdateParam(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckhttpExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/http"), + ), + }, + { + Config: testaccbigipltmprofilehttpUpdateParam(instName, "enforcement"), + Check: resource.ComposeTestCheckFunc( + testCheckhttpExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/http"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "CONNECT"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "DELETE"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "GET"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "HEAD"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "LOCK"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "POST"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "PROPFIND"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "PUT"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "TRACE"), + resource.TestCheckTypeSetElemAttr(resFullName, "enforcement.0.known_methods.*", "UNLOCK"), + resource.TestCheckResourceAttr(resFullName, "enforcement.0.unknown_method", "allow"), + resource.TestCheckResourceAttr(resFullName, "enforcement.0.max_header_count", "40"), + resource.TestCheckResourceAttr(resFullName, "enforcement.0.max_header_size", "80"), + ), + }, + }, + }) +} + +func TestAccBigipLtmProfileHttpUpdateHSTS(t *testing.T) { + t.Parallel() + var instName = "test-http-Update-hsts" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resHttpName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckHttpsDestroyed, + Steps: []resource.TestStep{ + { + Config: testaccbigipltmprofilehttpUpdateParam(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckhttpExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/http"), + ), + }, + { + Config: testaccbigipltmprofilehttpUpdateParam(instName, "hsts"), + Check: resource.ComposeTestCheckFunc( + testCheckhttpExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/http"), + resource.TestCheckResourceAttr(resFullName, "http_strict_transport_security.0.include_subdomains", "disabled"), + resource.TestCheckResourceAttr(resFullName, "http_strict_transport_security.0.preload", "enabled"), + resource.TestCheckResourceAttr(resFullName, "http_strict_transport_security.0.mode", "enabled"), + resource.TestCheckResourceAttr(resFullName, "http_strict_transport_security.0.maximum_age", "80"), + ), + }, + }, + }) +} + func TestAccBigipLtmProfileHttpImport(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -469,6 +550,22 @@ func testaccbigipltmprofilehttpUpdateParam(instName, updateParam string) string case "basic_auth_realm": resPrefix = fmt.Sprintf(`%s basic_auth_realm = "titanic"`, resPrefix) + case "enforcement": + resPrefix = fmt.Sprintf(`%s + enforcement { + known_methods = ["CONNECT","DELETE","GET","HEAD","LOCK","OPTIONS","POST","PROPFIND","PUT","TRACE","UNLOCK"] + unknown_method = "allow" + max_header_count = 40 + max_header_size = 80 + }`, resPrefix) + case "hsts": + resPrefix = fmt.Sprintf(`%s + http_strict_transport_security { + include_subdomains = "disabled" + preload = "enabled" + mode = "enabled" + maximum_age = 80 + }`, resPrefix) default: } return fmt.Sprintf(`%s diff --git a/docs/resources/bigip_ltm_profile_http.md b/docs/resources/bigip_ltm_profile_http.md index bbe46efed..b6ca857c0 100644 --- a/docs/resources/bigip_ltm_profile_http.md +++ b/docs/resources/bigip_ltm_profile_http.md @@ -83,7 +83,7 @@ resource "bigip_ltm_profile_http" "sanjose-http" { The `enforcement` block supports the following: -* `known_methods` - (Optional , `list`) Specifies which HTTP methods count as being known. Removing RFC-defined methods from this list will cause the HTTP filter to not recognize them. Default value is [CONNECT DELETE GET HEAD LOCK OPTIONS POST PROPFIND PUT TRACE UNLOCK]. If no value is specified, then default value will be added to such responses. In order to remove it, [""] list is to be passed. +* `known_methods` - (Optional , `list`) Specifies which HTTP methods count as being known. Removing RFC-defined methods from this list will cause the HTTP filter to not recognize them. Default value is [CONNECT DELETE GET HEAD LOCK OPTIONS POST PROPFIND PUT TRACE UNLOCK].If no value is specified while creating, then default value will be assigned. In order to remove it, [""] list is to be passed. * `unknown_method` - (Optional , `string`) Specifies whether to allow, reject or switch to pass-through mode when an unknown HTTP method is parsed. Default value is allow. If no string is specified, then default value will be assigned. From 5ee21a621a6bbe39281719ccbee45550a0bd7ea9 Mon Sep 17 00:00:00 2001 From: ramaniprateek Date: Fri, 6 Oct 2023 15:52:42 +0530 Subject: [PATCH 05/10] Added Log message --- bigip/resource_bigip_ltm_profile_http.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bigip/resource_bigip_ltm_profile_http.go b/bigip/resource_bigip_ltm_profile_http.go index 3cc8c65c5..c506db47b 100644 --- a/bigip/resource_bigip_ltm_profile_http.go +++ b/bigip/resource_bigip_ltm_profile_http.go @@ -272,7 +272,8 @@ func resourceBigipLtmProfileHttpCreate(ctx context.Context, d *schema.ResourceDa client := meta.(*bigip.BigIP) name := d.Get("name").(string) - + log.Printf("[INFO] Creating HTTP Profile:%+v ", name) + pss := &bigip.HttpProfile{ Name: name, } From c3009c3331fd4e3a784d3f917b3d62a366e7893d Mon Sep 17 00:00:00 2001 From: ramaniprateek Date: Fri, 6 Oct 2023 16:20:25 +0530 Subject: [PATCH 06/10] Fixed golangci-lint error --- bigip/resource_bigip_ltm_profile_http.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/bigip/resource_bigip_ltm_profile_http.go b/bigip/resource_bigip_ltm_profile_http.go index c506db47b..681330833 100644 --- a/bigip/resource_bigip_ltm_profile_http.go +++ b/bigip/resource_bigip_ltm_profile_http.go @@ -237,9 +237,9 @@ func resourceBigipLtmProfileHttp() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "known_methods": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, Optional: true, Description: "Specifies which HTTP methods count as being known. Removing RFC-defined methods from this list will cause the HTTP filter to not recognize them.", }, @@ -273,13 +273,12 @@ func resourceBigipLtmProfileHttpCreate(ctx context.Context, d *schema.ResourceDa name := d.Get("name").(string) log.Printf("[INFO] Creating HTTP Profile:%+v ", name) - + pss := &bigip.HttpProfile{ Name: name, } config := getHttpProfileConfig(d, pss) - err := client.AddHttpProfile(config) if err != nil { return diag.FromErr(err) @@ -393,7 +392,6 @@ func resourceBigipLtmProfileHttpRead(ctx context.Context, d *schema.ResourceData } _ = d.Set("xff_alternative_names", pp.XffAlternativeNames) - var enforcementList []interface{} enforcement := make(map[string]interface{}) enforcement["max_header_count"] = pp.Enforcement.MaxHeaderCount @@ -490,7 +488,7 @@ func getHttpProfileConfig(d *schema.ResourceData, config *bigip.HttpProfile) *bi config.XffAlternativeNames = setToInterfaceSlice(d.Get("xff_alternative_names").(*schema.Set)) config.LwsWidth = d.Get("lws_width").(int) p := d.Get("http_strict_transport_security") - + for _, r := range p.(*schema.Set).List() { config.Hsts.IncludeSubdomains = r.(map[string]interface{})["include_subdomains"].(string) config.Hsts.Mode = r.(map[string]interface{})["preload"].(string) @@ -498,7 +496,6 @@ func getHttpProfileConfig(d *schema.ResourceData, config *bigip.HttpProfile) *bi config.Hsts.MaximumAge = r.(map[string]interface{})["maximum_age"].(int) } - v := d.Get("enforcement") for _, r := range v.(*schema.Set).List() { From a0a14c73f6b8822cb10d04d93173a879b2d35daa Mon Sep 17 00:00:00 2001 From: Rohit Upadhyay Date: Fri, 6 Oct 2023 16:29:05 +0530 Subject: [PATCH 07/10] Added resource for OCSP and ocsp_stapling param to client_ssl_profile --- bigip/provider.go | 1 + .../resource_bigip_ltm_profile_ssl_client.go | 12 + bigip/resource_bigip_sys_ocsp.go | 336 ++++++++++++++++++ bigip/resource_bigip_sys_ocsp_test.go | 124 +++++++ .../resources/bigip_ltm_profile_client_ssl.md | 2 + docs/resources/bigip_sys_ocsp.md | 67 ++++ .../github.com/f5devcentral/go-bigip/ltm.go | 5 +- .../github.com/f5devcentral/go-bigip/sys.go | 55 +++ 8 files changed, 600 insertions(+), 2 deletions(-) create mode 100644 bigip/resource_bigip_sys_ocsp.go create mode 100644 bigip/resource_bigip_sys_ocsp_test.go create mode 100644 docs/resources/bigip_sys_ocsp.md diff --git a/bigip/provider.go b/bigip/provider.go index aa0312deb..d49ea16a3 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -139,6 +139,7 @@ func Provider() *schema.Provider { "bigip_sys_dns": resourceBigipSysDns(), "bigip_sys_iapp": resourceBigipSysIapp(), "bigip_sys_ntp": resourceBigipSysNtp(), + "bigip_sys_ocsp": resourceBigipSysOcsp(), "bigip_sys_provision": resourceBigipSysProvision(), "bigip_sys_snmp": resourceBigipSysSnmp(), "bigip_sys_snmp_traps": resourceBigipSysSnmpTraps(), diff --git a/bigip/resource_bigip_ltm_profile_ssl_client.go b/bigip/resource_bigip_ltm_profile_ssl_client.go index c8bc835cf..5d8d5589e 100644 --- a/bigip/resource_bigip_ltm_profile_ssl_client.go +++ b/bigip/resource_bigip_ltm_profile_ssl_client.go @@ -328,6 +328,13 @@ func resourceBigipLtmProfileClientSsl() *schema.Resource { Description: "ModSSL Methods enabled / disabled. Default is disabled.", }, + "ocsp_stapling": { + Type: schema.TypeString, + Optional: true, + Default: "disabled", + Description: "Specifies whether the system uses OCSP stapling.", + }, + "tm_options": { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, @@ -686,6 +693,10 @@ func resourceBigipLtmProfileClientSSLRead(ctx context.Context, d *schema.Resourc _ = d.Set("tm_options", tmOptions) } + if _, ok := d.GetOk("ocsp_stapling"); ok { + _ = d.Set("ocsp_stapling", obj.OcspStapling) + } + if _, ok := d.GetOk("proxy_ca_cert"); ok { _ = d.Set("proxy_ca_cert", obj.ProxyCaCert) } @@ -856,6 +867,7 @@ func getClientSslConfig(d *schema.ResourceData, config *bigip.ClientSSLProfile) config.CaFile = d.Get("ca_file").(string) config.CacheSize = d.Get("cache_size").(int) config.CacheTimeout = d.Get("cache_timeout").(int) + config.OcspStapling = d.Get("ocsp_stapling").(string) log.Printf("[DEBUG] Length of certKeyChains :%+v", len(certKeyChains)) log.Printf("[DEBUG] certKeyChains :%+v", certKeyChains) if len(certKeyChains) == 0 { diff --git a/bigip/resource_bigip_sys_ocsp.go b/bigip/resource_bigip_sys_ocsp.go new file mode 100644 index 000000000..88aef6ce4 --- /dev/null +++ b/bigip/resource_bigip_sys_ocsp.go @@ -0,0 +1,336 @@ +package bigip + +import ( + "context" + "encoding/json" + "fmt" + "log" + "os" + "strings" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/f5devcentral/go-bigip/f5teem" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceBigipSysOcsp() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBigipSysOcspCreate, + ReadContext: resourceBigipSysOcspRead, + UpdateContext: resourceBigipSysOcspUpdate, + DeleteContext: resourceBigipSysOcspDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Description: "Specifies the name of the OCSP responder. It should be of the pattern '/partition/name'", + Required: true, + }, + "proxy_server_pool": { + Type: schema.TypeString, + Description: "Specifies the proxy server pool the BIG-IP system uses to fetch the OCSP response. It should be of the pattern '/partition/pool-name'", + ConflictsWith: []string{"dns_resolver"}, + Optional: true, + }, + "dns_resolver": { + Type: schema.TypeString, + Description: "Specifies the internal DNS resolver the BIG-IP system uses to fetch the OCSP response. It should be of the pattern '/partition/resolver-name'", + ConflictsWith: []string{"proxy_server_pool"}, + Optional: true, + }, + "route_domain": { + Type: schema.TypeString, + Description: "Specifies the route domain for the OCSP responder", + Optional: true, + }, + "concurrent_connections_limit": { + Type: schema.TypeInt, + Description: "Specifies the maximum number of connections per second allowed for the OCSP certificate validator", + Optional: true, + Default: 50, + }, + "responder_url": { + Type: schema.TypeString, + Description: "Specifies the URL of the OCSP responder", + Optional: true, + }, + "connection_timeout": { + Type: schema.TypeInt, + Description: "Specifies the time interval that the BIG-IP system waits for before ending the connection to the OCSP responder, in seconds", + Optional: true, + Default: 8, + }, + "trusted_responders": { + Type: schema.TypeString, + Description: "Specifies the certificates used for validating the OCSP response", + Optional: true, + }, + "clock_skew": { + Type: schema.TypeInt, + Description: "Specifies the tolerable absolute difference in the clocks of the responder and the BIG-IP system, in seconds", + Optional: true, + Default: 300, + }, + "status_age": { + Type: schema.TypeInt, + Description: "Specifies the maximum allowed lag time that the BIG-IP system accepts for the 'thisUpdate' time in the OCSP response, in seconds", + Optional: true, + Default: 0, + }, + "strict_resp_cert_check": { + Type: schema.TypeString, + Description: "Specifies whether the responder's certificate is checked for an OCSP signing extension", + Optional: true, + Default: "enabled", + }, + "cache_timeout": { + Type: schema.TypeString, + Description: "Specifies the lifetime of the OCSP response in the cache, in seconds", + Optional: true, + Default: "indefinite", + }, + "cache_error_timeout": { + Type: schema.TypeInt, + Description: "Specifies the lifetime of an error response in the cache, in seconds. This value must be greater than connection_timeout", + Optional: true, + Default: 3600, + }, + "signer_cert": { + Type: schema.TypeString, + Description: "Specifies a certificate used to sign an OCSP request. It should be of the pattern '/partition/cert-name'", + Optional: true, + }, + "signer_key": { + Type: schema.TypeString, + Description: "Specifies a key used to sign an OCSP request. It should be of the pattern '/partition/key-name'", + Optional: true, + }, + "passphrase": { + Type: schema.TypeString, + Description: "Specifies a passphrase used to sign an OCSP request", + Sensitive: true, + Optional: true, + }, + "sign_hash": { + Type: schema.TypeString, + Description: "Specifies the hash algorithm used to sign an OCSP request", + Default: "sha256", + Optional: true, + }, + }, + } +} + +func resourceBigipSysOcspCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Get("name").(string) + + ocsp := &bigip.OCSP{ + Name: name, + } + + populateOcspConfig(ocsp, d) + + err := client.CreateOCSP(ocsp) + + if err != nil { + return diag.FromErr(err) + } + + d.SetId(name) + + if !client.Teem { + id := uuid.New() + uniqueID := id.String() + assetInfo := f5teem.AssetInfo{ + Name: "Terraform-provider-bigip", + Version: client.UserAgent, + Id: uniqueID, + } + apiKey := os.Getenv("TEEM_API_KEY") + teemDevice := f5teem.AnonymousClient(assetInfo, apiKey) + f := map[string]interface{}{ + "Terraform Version": client.UserAgent, + } + tsVer := strings.Split(client.UserAgent, "/") + err = teemDevice.Report(f, "bigip_sys_ocsp", tsVer[3]) + if err != nil { + log.Printf("[ERROR]Sending Telemetry data failed:%v", err) + } + } + + return resourceBigipSysOcspRead(ctx, d, meta) +} + +func resourceBigipSysOcspRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + id := d.Id() + id = strings.Trim(id, "/") + splitArr := strings.Split(id, "/") + if len(splitArr) != 2 { + return diag.Errorf("Invalid ID %s", id) + } + + name := splitArr[1] + partition := splitArr[0] + ocspFqdn := fmt.Sprintf("~%s~%s", partition, name) + + ocsp, err := client.GetOCSP(ocspFqdn) + if err != nil { + log.Printf("[ERROR] unable to retrieve ocsp %s: %s ", name, err) + return diag.FromErr(err) + } + + ocspJson, err := json.Marshal(ocsp) + if err != nil { + log.Printf("[ERROR] unable to marshal ocsp %s: %s ", name, err) + return diag.FromErr(err) + } + + log.Printf("[INFO] ocsp response: %+v", string(ocspJson)) + + d.Set("name", ocsp.FullPath) + + setOcspStateData(d, ocsp) + + return nil +} + +func resourceBigipSysOcspUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + id := d.Id() + id = strings.Trim(id, "/") + splitArr := strings.Split(id, "/") + if len(splitArr) != 2 { + return diag.Errorf("Invalid ID %s", id) + } + + name := splitArr[1] + partition := splitArr[0] + ocspFqdn := fmt.Sprintf("~%s~%s", partition, name) + + ocsp := &bigip.OCSP{ + Name: name, + } + populateOcspConfig(ocsp, d) + + err := client.ModifyOCSP(ocspFqdn, ocsp) + if err != nil { + return diag.FromErr(err) + } + + return resourceBigipSysOcspRead(ctx, d, meta) +} + +func resourceBigipSysOcspDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + id := d.Id() + id = strings.Trim(id, "/") + splitArr := strings.Split(id, "/") + if len(splitArr) != 2 { + return diag.Errorf("Invalid ID %s", id) + } + + name := splitArr[1] + partition := splitArr[0] + ocspFqdn := fmt.Sprintf("~%s~%s", partition, name) + + err := client.DeleteOCSP(ocspFqdn) + + if err != nil { + log.Printf("[ERROR] unable to delete ocsp %s: %s ", name, err) + return diag.FromErr(err) + } + d.SetId("") + return nil +} + +func populateOcspConfig(ocsp *bigip.OCSP, d *schema.ResourceData) { + if v, ok := d.GetOk("proxy_server_pool"); ok { + ocsp.ProxyServerPool = v.(string) + } + if v, ok := d.GetOk("dns_resolver"); ok { + ocsp.DnsResolver = v.(string) + } + if v, ok := d.GetOk("concurrent_connections_limit"); ok { + ocsp.ConcurrentConnectionsLimit = int64(v.(int)) + } + if v, ok := d.GetOk("responder_url"); ok { + ocsp.ResponderUrl = v.(string) + } + if v, ok := d.GetOk("route_domain"); ok { + ocsp.RouteDomain = v.(string) + } + if v, ok := d.GetOk("connection_timeout"); ok { + ocsp.ConnectionTimeout = int64(v.(int)) + } + if v, ok := d.GetOk("trusted_responder"); ok { + ocsp.TrustedResponders = v.(string) + } + if v, ok := d.GetOk("clock_skew"); ok { + ocsp.ClockSkew = int64(v.(int)) + } + if v, ok := d.GetOk("status_age"); ok { + ocsp.StatusAge = int64(v.(int)) + } + if v, ok := d.GetOk("strict_resp_cert_check"); ok { + ocsp.StrictRespCertCheck = v.(string) + } + if v, ok := d.GetOk("cache_timeout"); ok { + ocsp.CacheTimeout = v.(string) + } + if v, ok := d.GetOk("cache_error_timeout"); ok { + ocsp.CacheErrorTimeout = int64(v.(int)) + } + if v, ok := d.GetOk("signer_cert"); ok { + ocsp.SignerCert = v.(string) + } + if v, ok := d.GetOk("signer_key"); ok { + ocsp.SignerKey = v.(string) + } + if v, ok := d.GetOk("passphrase"); ok { + ocsp.Passphrase = v.(string) + } + if v, ok := d.GetOk("sign_hash"); ok { + ocsp.SignHash = v.(string) + } +} + +func setOcspStateData(d *schema.ResourceData, ocsp *bigip.OCSP) { + if ocsp.ProxyServerPool != "" { + d.Set("proxy_server_pool", ocsp.ProxyServerPool) + } else { + d.Set("dns_resolver", ocsp.DnsResolver) + } + if ocsp.RouteDomain != "" { + d.Set("route_domain", ocsp.RouteDomain) + } + if ocsp.ResponderUrl != "" { + d.Set("responder_url", ocsp.ResponderUrl) + } + if ocsp.TrustedResponders != "" { + d.Set("trusted_responders", ocsp.TrustedResponders) + } + if ocsp.SignerCert != "" { + d.Set("signer_cert", ocsp.SignerCert) + } + if ocsp.SignerKey != "" { + d.Set("signer_key", ocsp.SignerKey) + } + + d.Set("concurrent_connections_limit", ocsp.ConcurrentConnectionsLimit) + d.Set("clock_skew", ocsp.ClockSkew) + d.Set("status_age", ocsp.StatusAge) + d.Set("cache_timeout", ocsp.CacheTimeout) + d.Set("cache_error_timeout", ocsp.CacheErrorTimeout) + d.Set("connection_timeout", ocsp.ConnectionTimeout) + d.Set("strict_resp_cert_check", ocsp.StrictRespCertCheck) + d.Set("sign_hash", ocsp.SignHash) +} diff --git a/bigip/resource_bigip_sys_ocsp_test.go b/bigip/resource_bigip_sys_ocsp_test.go new file mode 100644 index 000000000..612540b98 --- /dev/null +++ b/bigip/resource_bigip_sys_ocsp_test.go @@ -0,0 +1,124 @@ +package bigip + +import ( + "encoding/json" + "fmt" + "strings" + "testing" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +const testSysOcspDNS = ` +resource "bigip_sys_ocsp" "test-ocsp" { + name = "/Common/test-ocsp" + dns_resolver = "/Common/f5-aws-dns" + signer_key = "/Common/le-ssl" + signer_cert = "/Common/le-ssl" + passphrase = "testabcdef" +} +` + +const testSysOcspProxy = ` +resource "bigip_sys_ocsp" "test-ocsp" { + name = "/Common/test-ocsp" + proxy_server_pool = "/Common/test-poolxyz" + signer_key = "/Common/le-ssl" + signer_cert = "/Common/le-ssl" + passphrase = "testabcdef" +} +` + +func TestAccBigipSysOCSP_create(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckOCSPDestroyed, + Steps: []resource.TestStep{ + { + Config: testSysOcspDNS, + Check: resource.ComposeTestCheckFunc( + testCheckOCSPExists("~Common~test-ocsp"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "name", "/Common/test-ocsp"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "dns_resolver", "/Common/f5-aws-dns"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "signer_key", "/Common/le-ssl"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "signer_cert", "/Common/le-ssl"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "passphrase", "testabcdef"), + ), + }, + { + Config: testSysOcspProxy, + Check: resource.ComposeTestCheckFunc( + testCheckOCSPExists("~Common~test-ocsp"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "name", "/Common/test-ocsp"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "proxy_server_pool", "/Common/test-poolxyz"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "signer_key", "/Common/le-ssl"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "signer_cert", "/Common/le-ssl"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "passphrase", "testabcdef"), + ), + }, + { + Config: testSysOcspProxy, + Check: resource.ComposeTestCheckFunc( + testCheckOCSPExists("~Common~test-ocsp"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "name", "/Common/test-ocsp"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "proxy_server_pool", "/Common/test-poolxyz"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "signer_key", "/Common/le-ssl"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "signer_cert", "/Common/le-ssl"), + resource.TestCheckResourceAttr("bigip_sys_ocsp.test-ocsp", "passphrase", "testabcdef"), + ), + ExpectNonEmptyPlan: false, + }, + }, + }) +} + +func testCheckOCSPExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + + p, err := client.GetOCSP(name) + if err != nil { + return err + } + if p == nil { + return fmt.Errorf("OCSP %s does not exist ", name) + } + + return nil + } +} + +func testCheckOCSPDestroyed(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + for _, rs := range s.RootModule().Resources { + if rs.Type != "bigip_sys_ocsp" { + continue + } + + id := rs.Primary.ID + id = strings.Trim(id, "/") + splitArr := strings.Split(id, "/") + if len(splitArr) != 2 { + return fmt.Errorf("Invalid ID %s", id) + } + + name := splitArr[1] + partition := splitArr[0] + ocspFqdn := fmt.Sprintf("~%s~%s", partition, name) + // client.DeleteOCSP(ocspFqdn) + ocsp, err := client.GetOCSP(ocspFqdn) + js, _ := json.Marshal(ocsp) + if err != nil { + return err + } + if ocsp != nil { + return fmt.Errorf("OCSP %s not destroyed, struct %+v, js %s", name, ocsp, string(js)) + } + } + return nil +} diff --git a/docs/resources/bigip_ltm_profile_client_ssl.md b/docs/resources/bigip_ltm_profile_client_ssl.md index d9635f611..fb8dd8c50 100644 --- a/docs/resources/bigip_ltm_profile_client_ssl.md +++ b/docs/resources/bigip_ltm_profile_client_ssl.md @@ -49,6 +49,8 @@ Don't insert empty fragments and No TLSv1.3 are listed as Enabled Options. `Usag * `cipher_group` - (Optional) Specifies the cipher group for the SSL server profile. It is mutually exclusive with the argument, `ciphers`. The default value is `none`. +* `ocsp_stapling` - (Optional) Specifies whether the system uses OCSP stapling. The default value is `disabled`. + * `peer_cert_mode` - (Optional) Specifies the way the system handles client certificates.When ignore, specifies that the system ignores certificates from client systems.When require, specifies that the system requires a client to present a valid certificate.When request, specifies that the system requests a valid certificate from a client but always authenticate the client. * `renegotiation` - (Optional) Enables or disables SSL renegotiation.When creating a new profile, the setting is provided by the parent profile diff --git a/docs/resources/bigip_sys_ocsp.md b/docs/resources/bigip_sys_ocsp.md new file mode 100644 index 000000000..43f937fc7 --- /dev/null +++ b/docs/resources/bigip_sys_ocsp.md @@ -0,0 +1,67 @@ +--- +layout: "bigip" +page_title: "BIG-IP: bigip_sys_ocsp" +subcategory: "System" +description: |- + Provides details about OCSP resource for BIG-IP +--- + +# bibip\_sys\_ocsp + +`bigip_sys_ocsp` Manages F5 BIG-IP OCSP responder using iControl REST. + +## Example Usage + +```hcl +resource "bigip_sys_ocsp" "test-ocsp" { + name = "/Uncommon/test-ocsp" + proxy_server_pool = "/Common/test-poolxyz" + signer_key = "/Common/le-ssl" + signer_cert = "/Common/le-ssl" + passphrase = "testabcdef" +} +``` + +## Argument Reference + +* `name` - (Required,type `string`) Name of the OCSP Responder. Name should be in pattern `/partition/ocsp_name`. + +* `proxy_server_pool` - (Required,type `string`) Specifies the proxy server pool the BIG-IP system uses to fetch the OCSP response. + +* `dns_resolver` - (Optional,type `string`) Specifies the internal DNS resolver the BIG-IP system uses to fetch the OCSP response. + +* `route_domain` - (Optional,type `string`) Specifies the route domain for the OCSP responder. + +* `concurrent_connections_limit` - (Optional,type `int`) Specifies the maximum number of connections per second allowed for the OCSP certificate validator. The default value is `50`. + +* `responder_url` - (Optional,type `string`) Specifies the URL of the OCSP responder. + +* `connection_timeout` - (Optional,type `int`) Specifies the time interval that the BIG-IP system waits for before ending the connection to the OCSP responder, in seconds. The default value is `8`. + +* `trusted_responders` - (Optional,type `string`) Specifies the certificates used for validating the OCSP response. + +* `clock_skew` - (Optional,type `int`) Specifies the time interval that the BIG-IP system allows for clock skew, in seconds. The default value is `300`. + +* `status_age` - (Optional,type `int`) Specifies the maximum allowed lag time that the BIG-IP system accepts for the 'thisUpdate' time in the OCSP response, in seconds. The default value is `0`. + +* `strict_resp_cert_check` - (Optional,type `string`) Specifies whether the responder's certificate is checked for an OCSP signing extension. The default value is `enabled`. + +* `cache_timeout` - (Optional,type `string`) Specifies the lifetime of the OCSP response in the cache, in seconds. The default value is `indefinite`. + +* `cache_error_timeout` - (Optional,type `string`) Specifies the lifetime of an error response in the cache, in seconds. This value must be greater than connection_timeout. The default value is `3600`. + +* `signer_cert` - (Required,type `string`) Specifies the certificate used to sign the OCSP request. + +* `signer_key` - (Required,type `string`) Specifies the key used to sign the OCSP request. + +* `passphrase` - (Optional,type `string`) Specifies a passphrase used to sign an OCSP request. + +* `sign_hash` - (Optional,type `string`) Specifies the hash algorithm used to sign the OCSP request. The default value is `sha256`. + + +## Importing +An existing OCSP can be imported into this resource by supplying the full path name ex : `/partition/name` +An example is below: +```sh +$ terraform import bigip_sys_ocsp.test-ocsp /Common/test-ocsp +``` diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index 4e57c326f..598c8ffe9 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -130,6 +130,7 @@ type ClientSSLProfile struct { Key string `json:"key,omitempty"` ModSslMethods string `json:"modSslMethods,omitempty"` Mode string `json:"mode,omitempty"` + OcspStapling string `json:"ocspStapling,omitempty"` TmOptions interface{} `json:"tmOptions,omitempty"` Passphrase string `json:"passphrase,omitempty"` PeerCertMode string `json:"peerCertMode,omitempty"` @@ -2100,7 +2101,7 @@ func (b *BigIP) GetClientSSLProfile(name string) (*ClientSSLProfile, error) { if !ok { return nil, nil } - log.Printf("------------------ssl profile: %+v-----------------", clientSSLProfile) + return &clientSSLProfile, nil } @@ -4006,4 +4007,4 @@ func (b *BigIP) GetLtmCipherGroup(name string) (*CipherGroupReq, error) { } return &cipherGroup, nil -} \ No newline at end of file +} diff --git a/vendor/github.com/f5devcentral/go-bigip/sys.go b/vendor/github.com/f5devcentral/go-bigip/sys.go index b9bfc764f..a69f2ea8f 100644 --- a/vendor/github.com/f5devcentral/go-bigip/sys.go +++ b/vendor/github.com/f5devcentral/go-bigip/sys.go @@ -239,6 +239,28 @@ type ExternalDGFile struct { Type string `json:"type"` } +type OCSP struct { + Name string `json:"name,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Partition string `json:"partition,omitempty"` + ProxyServerPool string `json:"proxyServerPool,omitempty"` + DnsResolver string `json:"dnsResolver,omitempty"` + RouteDomain string `json:"routeDomain,omitempty"` + ConcurrentConnectionsLimit int64 `json:"concurrentConnectionsLimit,omitempty"` + ResponderUrl string `json:"responderUrl,omitempty"` + ConnectionTimeout int64 `json:"timeout,omitempty"` + TrustedResponders string `json:"trustedResponders,omitempty"` + ClockSkew int64 `json:"clockSkew,omitempty"` + StatusAge int64 `json:"statusAge,omitempty"` + StrictRespCertCheck string `json:"strictRespCertCheck,omitempty"` + CacheTimeout string `json:"cacheTimeout,omitempty"` + CacheErrorTimeout int64 `json:"cacheErrorTimeout,omitempty"` + SignerCert string `json:"signerCert,omitempty"` + SignerKey string `json:"signerKey,omitempty"` + Passphrase string `json:"passphrase,omitempty"` + SignHash string `json:"signHash,omitempty"` +} + func (p *LogPublisher) MarshalJSON() ([]byte, error) { return json.Marshal(destinationsDTO{ Name: p.Name, @@ -995,3 +1017,36 @@ func (b *BigIP) UploadDataGroupFile(f *os.File, tmpName string) (*Upload, error) log.Printf("tmpName:%+v", tmpName) return b.Upload(f, info.Size(), uriShared, uriFileTransfer, uriUploads, fmt.Sprintf("%s", tmpName)) } + +func (b *BigIP) CreateOCSP(ocsp *OCSP) error { + return b.post(ocsp, uriSys, "crypto", "cert-validator", "ocsp") +} + +func (b *BigIP) ModifyOCSP(name string, ocsp *OCSP) error { + return b.put(ocsp, uriSys, "crypto", "cert-validator", "ocsp", name) +} + +func (b *BigIP) GetOCSP(name string) (*OCSP, error) { + var ocsp OCSP + err, _ := b.getForEntity(&ocsp, uriSys, "crypto", "cert-validator", "ocsp", name) + + if err != nil { + return nil, err + } + + js, err := json.Marshal(ocsp) + + if err != nil { + return nil, fmt.Errorf("error encountered while marshalling ocsp: %v", err) + } + + if string(js) == "{}" { + return nil, nil + } + + return &ocsp, nil +} + +func (b *BigIP) DeleteOCSP(name string) error { + return b.delete(uriSys, "crypto", "cert-validator", "ocsp", name) +} From 7352a5d953a1d87e5cdfc7b6dde940c38198c67c Mon Sep 17 00:00:00 2001 From: chinthalapalli Date: Tue, 10 Oct 2023 00:44:31 +0530 Subject: [PATCH 08/10] vendor sync --- bigip/version.go | 2 +- go.mod | 4 +- go.sum | 8 +- .../github.com/f5devcentral/go-bigip/ltm.go | 84 +++++++++---------- vendor/modules.txt | 4 +- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/bigip/version.go b/bigip/version.go index bf532b07c..facdd85c9 100644 --- a/bigip/version.go +++ b/bigip/version.go @@ -1,4 +1,4 @@ package bigip // ProviderVersion is set at build-time in the release process -var ProviderVersion = "1.19.0" +var ProviderVersion = "1.20.0" diff --git a/go.mod b/go.mod index 4bfe8550d..714e7daa1 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ require ( github.com/Azure/azure-storage-blob-go v0.13.0 github.com/Azure/go-autorest/autorest v0.11.18 github.com/Azure/go-autorest/autorest/adal v0.9.13 - github.com/f5devcentral/go-bigip v0.0.0-20230929101300-4ca00e7ed5fc - github.com/f5devcentral/go-bigip/f5teem v0.0.0-20230929101300-4ca00e7ed5fc + github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648 + github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648 github.com/google/uuid v1.3.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index fe532442b..f59259c2c 100644 --- a/go.sum +++ b/go.sum @@ -480,10 +480,10 @@ github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/f5devcentral/go-bigip v0.0.0-20230929101300-4ca00e7ed5fc h1:jWmvlICHswmQEL4qUc6CxIsQy2Guxwk4uE6jJWiE5/o= -github.com/f5devcentral/go-bigip v0.0.0-20230929101300-4ca00e7ed5fc/go.mod h1:0Lkr0fBU6O1yBxF2mt9JFwXpaFbIb/wAY7oM3dMJDdA= -github.com/f5devcentral/go-bigip/f5teem v0.0.0-20230929101300-4ca00e7ed5fc h1:tlODenRp43vLPGE20j+fgrDPNNH2MJ6HyqDcLKjYOmo= -github.com/f5devcentral/go-bigip/f5teem v0.0.0-20230929101300-4ca00e7ed5fc/go.mod h1:r7o5I22EvO+fps2u10bz4ZUlTlNHopQSWzVcW19hK3U= +github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648 h1:9PAZ2F7qRAJGXTaYDQ9VT9GjaC/gJ9bOeNUcxVP/Fuc= +github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648/go.mod h1:0Lkr0fBU6O1yBxF2mt9JFwXpaFbIb/wAY7oM3dMJDdA= +github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648 h1:WT+LOLH5/fiodf6Pnr6dAJ045Uk1Ga+5a1T0XouAocc= +github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648/go.mod h1:r7o5I22EvO+fps2u10bz4ZUlTlNHopQSWzVcW19hK3U= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index cc08cf463..5530761d3 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -1809,56 +1809,56 @@ type HttpProfiles struct { } type HttpProfile struct { - AcceptXff string `json:"acceptXff,omitempty"` - AppService string `json:"appService,omitempty"` - BasicAuthRealm string `json:"basicAuthRealm,omitempty"` - DefaultsFrom string `json:"defaultsFrom,omitempty"` - Description string `json:"description,omitempty"` - EncryptCookieSecret string `json:"encryptCookieSecret,omitempty"` - EncryptCookies []string `json:"encryptCookies,omitempty"` - FallbackHost string `json:"fallbackHost,omitempty"` - FallbackStatusCodes []string `json:"fallbackStatusCodes,omitempty"` - HeaderErase string `json:"headerErase,omitempty"` - HeaderInsert string `json:"headerInsert,omitempty"` - InsertXforwardedFor string `json:"insertXforwardedFor,omitempty"` - LwsSeparator string `json:"lwsSeparator,omitempty"` - LwsWidth int `json:"lwsWidth,omitempty"` - Name string `json:"name,omitempty"` - OneconnectTransformations string `json:"oneconnectTransformations,omitempty"` - TmPartition string `json:"tmPartition,omitempty"` - ProxyType string `json:"proxyType,omitempty"` - RedirectRewrite string `json:"redirectRewrite,omitempty"` - RequestChunking string `json:"requestChunking,omitempty"` - ResponseChunking string `json:"responseChunking,omitempty"` - ResponseHeadersPermitted []interface{} `json:"responseHeadersPermitted,omitempty"` - ServerAgentName string `json:"serverAgentName,omitempty"` - ViaHostName string `json:"viaHostName,omitempty"` - ViaRequest string `json:"viaRequest,omitempty"` - ViaResponse string `json:"viaResponse,omitempty"` - XffAlternativeNames []interface{} `json:"xffAlternativeNames,omitempty"` - Hsts HTTPStrictTransportSecurity `json:"hsts,omitempty"` - Enforcement Enforcement `json:"enforcement,omitempty"` + AcceptXff string `json:"acceptXff,omitempty"` + AppService string `json:"appService,omitempty"` + BasicAuthRealm string `json:"basicAuthRealm,omitempty"` + DefaultsFrom string `json:"defaultsFrom,omitempty"` + Description string `json:"description,omitempty"` + EncryptCookieSecret string `json:"encryptCookieSecret,omitempty"` + EncryptCookies []string `json:"encryptCookies,omitempty"` + FallbackHost string `json:"fallbackHost,omitempty"` + FallbackStatusCodes []string `json:"fallbackStatusCodes,omitempty"` + HeaderErase string `json:"headerErase,omitempty"` + HeaderInsert string `json:"headerInsert,omitempty"` + InsertXforwardedFor string `json:"insertXforwardedFor,omitempty"` + LwsSeparator string `json:"lwsSeparator,omitempty"` + LwsWidth int `json:"lwsWidth,omitempty"` + Name string `json:"name,omitempty"` + OneconnectTransformations string `json:"oneconnectTransformations,omitempty"` + TmPartition string `json:"tmPartition,omitempty"` + ProxyType string `json:"proxyType,omitempty"` + RedirectRewrite string `json:"redirectRewrite,omitempty"` + RequestChunking string `json:"requestChunking,omitempty"` + ResponseChunking string `json:"responseChunking,omitempty"` + ResponseHeadersPermitted []interface{} `json:"responseHeadersPermitted,omitempty"` + ServerAgentName string `json:"serverAgentName,omitempty"` + ViaHostName string `json:"viaHostName,omitempty"` + ViaRequest string `json:"viaRequest,omitempty"` + ViaResponse string `json:"viaResponse,omitempty"` + XffAlternativeNames []interface{} `json:"xffAlternativeNames,omitempty"` + Hsts HTTPStrictTransportSecurity `json:"hsts,omitempty"` + Enforcement Enforcement `json:"enforcement,omitempty"` } type HTTPStrictTransportSecurity struct { - IncludeSubdomains string `json:"includeSubdomains,omitempty"` - MaximumAge int `json:"maximumAge,omitempty"` - Mode string `json:"mode,omitempty"` - Preload string `json:"preload,omitempty"` + IncludeSubdomains string `json:"includeSubdomains,omitempty"` + MaximumAge int `json:"maximumAge,omitempty"` + Mode string `json:"mode,omitempty"` + Preload string `json:"preload,omitempty"` } type Enforcement struct { - KnownMethods []string `json:"knownMethods,omitempty"` - ExcessClientHeaders string - ExcessServerHeaders string - MaxHeaderCount int `json:"maxHeaderCount,omitempty"` - MaxHeaderSize int `json:"maxHeaderSize,omitempty"` - MaxRequests int + KnownMethods []string `json:"knownMethods,omitempty"` + ExcessClientHeaders string + ExcessServerHeaders string + MaxHeaderCount int `json:"maxHeaderCount,omitempty"` + MaxHeaderSize int `json:"maxHeaderSize,omitempty"` + MaxRequests int OversizeClientHeaders string OversizeServerHeaders string - Pipeline string - TruncatedRedirects string - UnknownMethod string `json:"unknownMethod,omitempty"` + Pipeline string + TruncatedRedirects string + UnknownMethod string `json:"unknownMethod,omitempty"` } type OneconnectProfiles struct { diff --git a/vendor/modules.txt b/vendor/modules.txt index d98666a43..1d3dd33f8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,10 +42,10 @@ github.com/apparentlymart/go-textseg/v13/textseg # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/f5devcentral/go-bigip v0.0.0-20230929101300-4ca00e7ed5fc +# github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648 ## explicit; go 1.20 github.com/f5devcentral/go-bigip -# github.com/f5devcentral/go-bigip/f5teem v0.0.0-20230929101300-4ca00e7ed5fc +# github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648 ## explicit; go 1.13 github.com/f5devcentral/go-bigip/f5teem # github.com/fatih/color v1.13.0 From 182638767fed6c3687d8bc6d50fca8bb370758dd Mon Sep 17 00:00:00 2001 From: Rohit Upadhyay Date: Wed, 11 Oct 2023 15:39:43 +0530 Subject: [PATCH 09/10] Added ocsp attributes for ssl_key_cert and ssl_certificate rresources --- bigip/resource_bigip_ssl_certificate.go | 70 +++++++++++- bigip/resource_bigip_ssl_certificate_test.go | 34 ++++++ bigip/resource_bigip_ssl_key_cert.go | 64 ++++++++++- bigip/resource_bigip_ssl_key_cert_test.go | 35 ++++++ docs/resources/bigip_ssl_certificate.md | 6 + docs/resources/bigip_ssl_key_cert.md | 5 + .../github.com/f5devcentral/go-bigip/sys.go | 108 +++++++++--------- 7 files changed, 263 insertions(+), 59 deletions(-) diff --git a/bigip/resource_bigip_ssl_certificate.go b/bigip/resource_bigip_ssl_certificate.go index 0391dd753..d0fc14d80 100644 --- a/bigip/resource_bigip_ssl_certificate.go +++ b/bigip/resource_bigip_ssl_certificate.go @@ -39,7 +39,6 @@ func resourceBigipSslCertificate() *schema.Resource { //ForceNew: true, Description: "Content of certificate on Disk", }, - "partition": { Type: schema.TypeString, Optional: true, @@ -47,6 +46,21 @@ func resourceBigipSslCertificate() *schema.Resource { Description: "Partition of ssl certificate", ValidateFunc: validatePartitionName, }, + "monitoring_type": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies the type of monitoring used", + }, + "issuer_cert": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies the issuer certificate", + }, + "ocsp": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies the OCSP responder", + }, "full_path": { Type: schema.TypeString, Optional: true, @@ -64,7 +78,19 @@ func resourceBigipSslCertificateCreate(ctx context.Context, d *schema.ResourceDa certPath := d.Get("content").(string) partition := d.Get("partition").(string) - err := client.UploadCertificate(name, certPath, partition) + cert := &bigip.Certificate{ + Name: name, + Partition: partition, + } + + if val, ok := d.GetOk("monitoring_type"); ok { + cert.CertValidationOptions = []string{val.(string)} + } + if val, ok := d.GetOk("issuer_cert"); ok { + cert.IssuerCert = val.(string) + } + + err := client.UploadCertificate(certPath, cert) if err != nil { return diag.FromErr(fmt.Errorf("error in Importing certificate (%s): %s", name, err)) } @@ -88,6 +114,17 @@ func resourceBigipSslCertificateCreate(ctx context.Context, d *schema.ResourceDa log.Printf("[ERROR]Sending Telemetry data failed:%v", err) } } + + if val, ok := d.GetOk("ocsp"); ok { + certValidState := &bigip.CertValidatorState{Name: val.(string)} + certValidRef := &bigip.CertValidatorReference{} + certValidRef.Items = append(certValidRef.Items, *certValidState) + cert.CertValidatorRef = certValidRef + err = client.UpdateCertificate(certPath, cert) + if err != nil { + log.Printf("[ERROR]Unable to add ocsp to the certificate:%v", err) + } + } return resourceBigipSslCertificateRead(ctx, d, meta) } @@ -119,6 +156,11 @@ func resourceBigipSslCertificateRead(ctx context.Context, d *schema.ResourceData _ = d.Set("name", certificate.Name) _ = d.Set("partition", certificate.Partition) _ = d.Set("full_path", certificate.FullPath) + _ = d.Set("issuer_cert", certificate.IssuerCert) + if certificate.CertValidationOptions != nil && len(certificate.CertValidationOptions) > 0 { + monitor_type := certificate.CertValidationOptions[0] + _ = d.Set("monitoring_type", monitor_type) + } return nil } @@ -129,10 +171,26 @@ func resourceBigipSslCertificateUpdate(ctx context.Context, d *schema.ResourceDa log.Println("[INFO] Certificate Name " + name) certpath := d.Get("content").(string) partition := d.Get("partition").(string) - /*if !strings.HasSuffix(name, ".crt") { - name = name + ".crt" - }*/ - err := client.UpdateCertificate(name, certpath, partition) + + cert := &bigip.Certificate{ + Name: name, + Partition: partition, + } + + if val, ok := d.GetOk("monitoring_type"); ok { + cert.CertValidationOptions = []string{val.(string)} + } + if val, ok := d.GetOk("issuer_cert"); ok { + cert.IssuerCert = val.(string) + } + if val, ok := d.GetOk("ocsp"); ok { + certValidState := &bigip.CertValidatorState{Name: val.(string)} + certValidRef := &bigip.CertValidatorReference{} + certValidRef.Items = append(certValidRef.Items, *certValidState) + cert.CertValidatorRef = certValidRef + } + + err := client.UpdateCertificate(certpath, cert) if err != nil { return diag.FromErr(fmt.Errorf("error in Importing certificate (%s): %s", name, err)) } diff --git a/bigip/resource_bigip_ssl_certificate_test.go b/bigip/resource_bigip_ssl_certificate_test.go index 46c08025e..7b634a648 100644 --- a/bigip/resource_bigip_ssl_certificate_test.go +++ b/bigip/resource_bigip_ssl_certificate_test.go @@ -28,6 +28,17 @@ resource "bigip_ssl_certificate" "test-cert" { } ` +var TestSslCertOCSPResource = ` +resource "bigip_ssl_certificate" "ssl-test-certificate-tc1" { + name = "test-certificate" + content = "${file("` + folder + `/../examples/mycertocspv2.crt")}" + partition = "Common" + monitoring_type = "ocsp" + issuer_cert = "/Common/MyCA" + ocsp = "/Common/testocsp1" +} +` + func TestAccBigipSslCertificateImportToBigip(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -88,6 +99,29 @@ func TestAccBigipSslCertificateTCs(t *testing.T) { }) } +func TestAccBigipSslCertificateOCSP(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testChecksslcertificateDestroyed, + Steps: []resource.TestStep{ + { + Config: TestSslCertOCSPResource, + Check: resource.ComposeTestCheckFunc( + testChecksslcertificateExists("test-certificate", true), + resource.TestCheckResourceAttr("bigip_ssl_certificate.ssl-test-certificate-tc1", "name", "test-certificate"), + resource.TestCheckResourceAttr("bigip_ssl_certificate.ssl-test-certificate-tc1", "partition", "Common"), + resource.TestCheckResourceAttr("bigip_ssl_certificate.ssl-test-certificate-tc1", "monitoring_type", "ocsp"), + resource.TestCheckResourceAttr("bigip_ssl_certificate.ssl-test-certificate-tc1", "issuer_cert", "/Common/MyCA"), + resource.TestCheckResourceAttr("bigip_ssl_certificate.ssl-test-certificate-tc1", "ocsp", "/Common/testocsp1"), + ), + }, + }, + }) +} + func testChecksslcertificateExists(name string, exists bool) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*bigip.BigIP) diff --git a/bigip/resource_bigip_ssl_key_cert.go b/bigip/resource_bigip_ssl_key_cert.go index c25a4f481..e95d01cf0 100644 --- a/bigip/resource_bigip_ssl_key_cert.go +++ b/bigip/resource_bigip_ssl_key_cert.go @@ -58,6 +58,21 @@ func resourceBigipSSLKeyCert() *schema.Resource { Computed: true, Description: "Full Path Name of ssl certificate", }, + "cert_monitoring_type": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies the type of monitoring used.", + }, + "issuer_cert": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies the issuer certificate", + }, + "cert_ocsp": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies the OCSP responder", + }, "passphrase": { Type: schema.TypeString, Optional: true, @@ -105,7 +120,19 @@ func resourceBigipSSLKeyCertCreate(ctx context.Context, d *schema.ResourceData, if err != nil { return diag.FromErr(fmt.Errorf("error while adding the ssl key: %v", err)) } - err = client.UploadCertificate(certName, certPath, partition) + + cert := &bigip.Certificate{ + Name: certName, + Partition: partition, + } + if val, ok := d.GetOk("cert_monitoring_type"); ok { + cert.CertValidationOptions = []string{val.(string)} + } + if val, ok := d.GetOk("issuer_cert"); ok { + cert.IssuerCert = val.(string) + } + + err = client.UploadCertificate(certPath, cert) if err != nil { return diag.FromErr(fmt.Errorf("error while uploading the ssl cert: %v", err)) } @@ -114,6 +141,17 @@ func resourceBigipSSLKeyCertCreate(ctx context.Context, d *schema.ResourceData, return diag.FromErr(fmt.Errorf("error while ending transaction: %d", err)) } + if val, ok := d.GetOk("cert_ocsp"); ok { + certValidState := &bigip.CertValidatorState{Name: val.(string)} + certValidRef := &bigip.CertValidatorReference{} + certValidRef.Items = append(certValidRef.Items, *certValidState) + cert.CertValidatorRef = certValidRef + err = client.UpdateCertificate(certPath, cert) + if err != nil { + log.Printf("[ERROR]Unable to add ocsp to the certificate:%v", err) + } + } + id := keyName + "_" + certName d.SetId(id) return resourceBigipSSLKeyCertRead(ctx, d, meta) @@ -147,6 +185,11 @@ func resourceBigipSSLKeyCertRead(ctx context.Context, d *schema.ResourceData, me d.Set("cert_name", certificate.Name) d.Set("cert_full_path", certificate.FullPath) d.Set("partition", key.Partition) + d.Set("issuer_cert", certificate.IssuerCert) + if certificate.CertValidationOptions != nil && len(certificate.CertValidationOptions) > 0 { + monitor_type := certificate.CertValidationOptions[0] + _ = d.Set("cert_monitoring_type", monitor_type) + } return nil } @@ -184,7 +227,24 @@ func resourceBigipSSLKeyCertUpdate(ctx context.Context, d *schema.ResourceData, return diag.FromErr(fmt.Errorf("error while trying to modify the ssl key (%s): %s", keyFullPath, err)) } - err = client.UpdateCertificate(certName, certPath, partition) + cert := &bigip.Certificate{ + Name: certName, + Partition: partition, + } + if val, ok := d.GetOk("cert_monitoring_type"); ok { + cert.CertValidationOptions = []string{val.(string)} + } + if val, ok := d.GetOk("issuer_cert"); ok { + cert.IssuerCert = val.(string) + } + if val, ok := d.GetOk("cert_ocsp"); ok { + certValidState := &bigip.CertValidatorState{Name: val.(string)} + certValidRef := &bigip.CertValidatorReference{} + certValidRef.Items = append(certValidRef.Items, *certValidState) + cert.CertValidatorRef = certValidRef + } + + err = client.UpdateCertificate(certPath, cert) if err != nil { return diag.FromErr(fmt.Errorf("error while updating the ssl certificate (%s): %s", certName, err)) } diff --git a/bigip/resource_bigip_ssl_key_cert_test.go b/bigip/resource_bigip_ssl_key_cert_test.go index 235811e3f..f1bf2b99d 100644 --- a/bigip/resource_bigip_ssl_key_cert_test.go +++ b/bigip/resource_bigip_ssl_key_cert_test.go @@ -42,6 +42,19 @@ resource "bigip_ltm_profile_server_ssl" "test-ServerSsl" { } ` +var sslProfileCertKeyOCSP = ` +resource "bigip_ssl_key_cert" "testkeycert" { + partition = "Common" + key_name = "ssl-test-key" + key_content = "${file("` + folder + `/../examples/mycertocspv2.pem")}" + cert_name = "ssl-test-cert" + cert_content = "${file("` + folder + `/../examples/mycertocspv2.crt")}" + cert_monitoring_type = "ocsp" + issuer_cert = "/Common/MyCA" + cert_ocsp = "/Common/testocsp1" +} +` + func TestAccBigipSSLCertKeyCreate(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -112,3 +125,25 @@ func TestAccBigipSSLCertKeyCreateCertKeyProfile(t *testing.T) { }, }) } + +func TestAccBigipSSLCertKeyCreateCertKeyProfileOCSP(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: sslProfileCertKeyOCSP, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("bigip_ssl_key_cert.testkeycert", "key_name", "ssl-test-key"), + resource.TestCheckResourceAttr("bigip_ssl_key_cert.testkeycert", "cert_name", "ssl-test-cert"), + resource.TestCheckResourceAttr("bigip_ssl_key_cert.testkeycert", "partition", "Common"), + resource.TestCheckResourceAttr("bigip_ssl_key_cert.testkeycert", "cert_monitoring_type", "ocsp"), + resource.TestCheckResourceAttr("bigip_ssl_key_cert.testkeycert", "issuer_cert", "/Common/MyCA"), + resource.TestCheckResourceAttr("bigip_ssl_key_cert.testkeycert", "cert_ocsp", "/Common/testocsp1"), + ), + }, + }, + }) +} diff --git a/docs/resources/bigip_ssl_certificate.md b/docs/resources/bigip_ssl_certificate.md index 2ea0fba54..f48032b85 100644 --- a/docs/resources/bigip_ssl_certificate.md +++ b/docs/resources/bigip_ssl_certificate.md @@ -33,3 +33,9 @@ resource "bigip_ssl_certificate" "test-cert" { * `content` - (Required) Content of certificate on Local Disk,path of SSL certificate will be provided to terraform `file` function * `partition` - Partition on to SSL Certificate to be imported. The parameter is not required when running terraform import operation. In such case the name must be provided in full_path format. + +* `monitoring_type` - Specifies the type of monitoring used. + +* `issuer_cert` - Specifies the issuer certificate. + +* `ocsp` - Specifies the OCSP responder. diff --git a/docs/resources/bigip_ssl_key_cert.md b/docs/resources/bigip_ssl_key_cert.md index 570cca38e..0b14d1d4f 100644 --- a/docs/resources/bigip_ssl_key_cert.md +++ b/docs/resources/bigip_ssl_key_cert.md @@ -42,6 +42,11 @@ resource "bigip_ssl_key_cert" "testkeycert" { * `passphrase` - (Optional,type `string`) Passphrase on the SSL key. +* `cert_monitoring_type` - (Optional,type `string`) Specifies the type of monitoring used. + +* `issuer_cert` - (Optional,type `string`) Specifies the issuer certificate. + +* `cert_ocsp` - (Optional,type `string`) Specifies the OCSP responder. ## Attribute Reference diff --git a/vendor/github.com/f5devcentral/go-bigip/sys.go b/vendor/github.com/f5devcentral/go-bigip/sys.go index a69f2ea8f..0a2f63c7f 100644 --- a/vendor/github.com/f5devcentral/go-bigip/sys.go +++ b/vendor/github.com/f5devcentral/go-bigip/sys.go @@ -320,38 +320,49 @@ type Certificates struct { // Certificate represents an SSL Certificate. type Certificate struct { - AppService string `json:"appService,omitempty"` - CachePath string `json:"cachePath,omitempty"` - CertificateKeyCurveName string `json:"certificateKeyCurveName,omitempty"` - CertificateKeySize int `json:"certificateKeySize,omitempty"` - CertValidationOptions string `json:"certValidationOptions,omitempty"` - Checksum string `json:"checksum,omitempty"` - CreatedBy string `json:"createdBy,omitempty"` - CreateTime string `json:"createTime,omitempty"` - Email string `json:"email,omitempty"` - ExpirationDate int64 `json:"expirationDate,omitempty"` - ExpirationString string `json:"expirationString,omitempty"` - Fingerprint string `json:"fingerprint,omitempty"` - FullPath string `json:"fullPath,omitempty"` - Generation int `json:"generation,omitempty"` - IsBundle string `json:"isBundle,omitempty"` - IsDynamic string `json:"isDynamic,omitempty"` - Issuer string `json:"issuer,omitempty"` - IssuerCert string `json:"issuerCert,omitempty"` - KeyType string `json:"keyType,omitempty"` - LastUpdateTime string `json:"lastUpdateTime,omitempty"` - Mode int `json:"mode,omitempty"` - Name string `json:"name,omitempty"` - Partition string `json:"partition,omitempty"` - Revision int `json:"revision,omitempty"` - SerialNumber string `json:"serialNumber,omitempty"` - Size uint64 `json:"size,omitempty"` - SourcePath string `json:"sourcePath,omitempty"` - Subject string `json:"subject,omitempty"` - SubjectAlternativeName string `json:"subjectAlternativeName,omitempty"` - SystemPath string `json:"systemPath,omitempty"` - UpdatedBy string `json:"updatedBy,omitempty"` - Version int `json:"version,omitempty"` + AppService string `json:"appService,omitempty"` + CachePath string `json:"cachePath,omitempty"` + CertificateKeyCurveName string `json:"certificateKeyCurveName,omitempty"` + CertificateKeySize int `json:"certificateKeySize,omitempty"` + CertValidationOptions []string `json:"certValidationOptions,omitempty"` + Checksum string `json:"checksum,omitempty"` + CreatedBy string `json:"createdBy,omitempty"` + CreateTime string `json:"createTime,omitempty"` + Email string `json:"email,omitempty"` + ExpirationDate int64 `json:"expirationDate,omitempty"` + ExpirationString string `json:"expirationString,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` + FullPath string `json:"fullPath,omitempty"` + Generation int `json:"generation,omitempty"` + IsBundle string `json:"isBundle,omitempty"` + IsDynamic string `json:"isDynamic,omitempty"` + Issuer string `json:"issuer,omitempty"` + IssuerCert string `json:"issuerCert,omitempty"` + KeyType string `json:"keyType,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + Mode int `json:"mode,omitempty"` + Name string `json:"name,omitempty"` + Partition string `json:"partition,omitempty"` + Revision int `json:"revision,omitempty"` + SerialNumber string `json:"serialNumber,omitempty"` + Size uint64 `json:"size,omitempty"` + SourcePath string `json:"sourcePath,omitempty"` + Subject string `json:"subject,omitempty"` + SubjectAlternativeName string `json:"subjectAlternativeName,omitempty"` + SystemPath string `json:"systemPath,omitempty"` + UpdatedBy string `json:"updatedBy,omitempty"` + Version int `json:"version,omitempty"` + CertValidatorRef *CertValidatorReference `json:"certValidatorsReference,omitempty"` +} + +type CertValidatorReference struct { + Items []CertValidatorState `json:"items,omitempty"` +} + +type CertValidatorState struct { + Name string `json:"name,omitempty"` + Partition string `json:"partition,omitempty"` + FullPath string `json:"fullPath,omitempty"` } // Keys represents a list of installed keys. @@ -429,25 +440,22 @@ func (b *BigIP) ModifyExternalDatagroupfile(dgName string, dataGroup *ExternalDG // ModifyCertificate installs a certificate. func (b *BigIP) ModifyCertificate(certName string, cert *Certificate) error { - return b.patch(cert, uriSys, uriFile, uriSslCert, certName) + return b.patch(cert, uriSys, uriFile, uriSslCert, certName, "?expandSubcollections=true") } // UploadCertificate copies a certificate local disk to BIGIP -func (b *BigIP) UploadCertificate(certname, certpath, partition string) error { +func (b *BigIP) UploadCertificate(certpath string, cert *Certificate) error { certbyte := []byte(certpath) - _, err := b.UploadBytes(certbyte, certname) + _, err := b.UploadBytes(certbyte, cert.Name) if err != nil { return err } - sourcepath := "file://" + REST_DOWNLOAD_PATH + "/" + certname + sourcepath := "file://" + REST_DOWNLOAD_PATH + "/" + cert.Name log.Printf("[DEBUG] sourcepath :%+v", sourcepath) - cert := Certificate{ - Name: certname, - SourcePath: sourcepath, - Partition: partition, - } + + cert.SourcePath = sourcepath log.Printf("cert: %+v\n", cert) - err = b.AddCertificate(&cert) + err = b.AddCertificate(cert) if err != nil { return err } @@ -474,20 +482,18 @@ func (b *BigIP) DeleteCertificate(name string) error { } // UpdateCertificate copies a certificate local disk to BIGIP -func (b *BigIP) UpdateCertificate(certname, certpath, partition string) error { +func (b *BigIP) UpdateCertificate(certpath string, cert *Certificate) error { certbyte := []byte(certpath) - _, err := b.UploadBytes(certbyte, certname) + _, err := b.UploadBytes(certbyte, cert.Name) if err != nil { return err } - sourcepath := "file://" + REST_DOWNLOAD_PATH + "/" + certname - cert := Certificate{ - Name: certname, - SourcePath: sourcepath, - } - certName := fmt.Sprintf("/%s/%s", partition, certname) + sourcepath := "file://" + REST_DOWNLOAD_PATH + "/" + cert.Name + + cert.SourcePath = sourcepath + certName := fmt.Sprintf("/%s/%s", cert.Partition, cert.Name) log.Printf("certName: %+v\n", certName) - err = b.ModifyCertificate(certName, &cert) + err = b.ModifyCertificate(certName, cert) if err != nil { return err } From 62b94e686b8656572a2a3a064f10e688417070c8 Mon Sep 17 00:00:00 2001 From: chinthalapalli Date: Wed, 11 Oct 2023 23:05:16 +0530 Subject: [PATCH 10/10] updated vendor sync for sys changes --- bigip/resource_bigip_ssl_certificate.go | 4 ++-- go.mod | 4 ++-- go.sum | 8 ++++---- vendor/modules.txt | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bigip/resource_bigip_ssl_certificate.go b/bigip/resource_bigip_ssl_certificate.go index d0fc14d80..6396a6684 100644 --- a/bigip/resource_bigip_ssl_certificate.go +++ b/bigip/resource_bigip_ssl_certificate.go @@ -158,8 +158,8 @@ func resourceBigipSslCertificateRead(ctx context.Context, d *schema.ResourceData _ = d.Set("full_path", certificate.FullPath) _ = d.Set("issuer_cert", certificate.IssuerCert) if certificate.CertValidationOptions != nil && len(certificate.CertValidationOptions) > 0 { - monitor_type := certificate.CertValidationOptions[0] - _ = d.Set("monitoring_type", monitor_type) + monitorType := certificate.CertValidationOptions[0] + _ = d.Set("monitoring_type", monitorType) } return nil diff --git a/go.mod b/go.mod index 714e7daa1..71e4788bc 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ require ( github.com/Azure/azure-storage-blob-go v0.13.0 github.com/Azure/go-autorest/autorest v0.11.18 github.com/Azure/go-autorest/autorest/adal v0.9.13 - github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648 - github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648 + github.com/f5devcentral/go-bigip v0.0.0-20231011173025-84b03e0e0bf7 + github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231011173025-84b03e0e0bf7 github.com/google/uuid v1.3.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index f59259c2c..f76bf769b 100644 --- a/go.sum +++ b/go.sum @@ -480,10 +480,10 @@ github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648 h1:9PAZ2F7qRAJGXTaYDQ9VT9GjaC/gJ9bOeNUcxVP/Fuc= -github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648/go.mod h1:0Lkr0fBU6O1yBxF2mt9JFwXpaFbIb/wAY7oM3dMJDdA= -github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648 h1:WT+LOLH5/fiodf6Pnr6dAJ045Uk1Ga+5a1T0XouAocc= -github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648/go.mod h1:r7o5I22EvO+fps2u10bz4ZUlTlNHopQSWzVcW19hK3U= +github.com/f5devcentral/go-bigip v0.0.0-20231011173025-84b03e0e0bf7 h1:xaK/uXNpvs510yY0PiNGL6Ak+X6zh3Vf7WpOI2e8/JY= +github.com/f5devcentral/go-bigip v0.0.0-20231011173025-84b03e0e0bf7/go.mod h1:0Lkr0fBU6O1yBxF2mt9JFwXpaFbIb/wAY7oM3dMJDdA= +github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231011173025-84b03e0e0bf7 h1:p76I5H3ztS0IqokrJHJyFf67xsEtzE/wKDZbrBkN99w= +github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231011173025-84b03e0e0bf7/go.mod h1:r7o5I22EvO+fps2u10bz4ZUlTlNHopQSWzVcW19hK3U= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= diff --git a/vendor/modules.txt b/vendor/modules.txt index 1d3dd33f8..57416ef9f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,10 +42,10 @@ github.com/apparentlymart/go-textseg/v13/textseg # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/f5devcentral/go-bigip v0.0.0-20231009171253-d493844bd648 +# github.com/f5devcentral/go-bigip v0.0.0-20231011173025-84b03e0e0bf7 ## explicit; go 1.20 github.com/f5devcentral/go-bigip -# github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231009171253-d493844bd648 +# github.com/f5devcentral/go-bigip/f5teem v0.0.0-20231011173025-84b03e0e0bf7 ## explicit; go 1.13 github.com/f5devcentral/go-bigip/f5teem # github.com/fatih/color v1.13.0