Repository: cloudflare/cloudflare-go
Pull request #1516 (2024-03-07 22:16:33)

AUTH-5959 add support for access mutual tls hostname settings
## Description

Add support for list and update of access mTLS hostname settings
docs: https://developers.cloudflare.com/api/operations/access-mtls-authentication-update-an-mtls-certificate-settings

## Has your change been tested?

unit tests

## Screenshots (if appropriate):

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [x] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This change is using publicly documented in [cloudflare/api-schemas](https://github.com/cloudflare/api-schemas) 
      and relies on stable APIs.


github-actions[bot]: Oops! It looks like no changelog entry is attached to this PR. Please include a release note as described in https://github.com/cloudflare/cloudflare-go/blob/master/docs/changelog-process.md.

Example: 

~~~
```release-note:TYPE
Release note
```
~~~

If you do not require a release note to be included, please add the `workflow/skip-changelog-entry` label.

Patch:
diff --git a/.changelog/1516.txt b/.changelog/1516.txt
new file mode 100644
index 000000000..87346e8ca
--- /dev/null
+++ b/.changelog/1516.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+access_mutual_tls_certificates: add support for mutual tls hostname settings
+```
\ No newline at end of file
diff --git a/access_mutual_tls_certificates.go b/access_mutual_tls_certificates.go
index 393476c42..9d4e413b1 100644
--- a/access_mutual_tls_certificates.go
+++ b/access_mutual_tls_certificates.go
@@ -58,6 +58,21 @@ type UpdateAccessMutualTLSCertificateParams struct {
 	AssociatedHostnames []string  `json:"associated_hostnames,omitempty"`
 }
 
+type AccessMutualTLSHostnameSettings struct {
+	ChinaNetwork                *bool  `json:"china_network,omitempty"`
+	ClientCertificateForwarding *bool  `json:"client_certificate_forwarding,omitempty"`
+	Hostname                    string `json:"hostname,omitempty"`
+}
+
+type GetAccessMutualTLSHostnameSettingsResponse struct {
+	Response
+	Result []AccessMutualTLSHostnameSettings `json:"result"`
+}
+
+type UpdateAccessMutualTLSHostnameSettingsParams struct {
+	Settings []AccessMutualTLSHostnameSettings `json:"settings,omitempty"`
+}
+
 // ListAccessMutualTLSCertificates returns all Access TLS certificates
 //
 // Account API Reference: https://developers.cloudflare.com/api/operations/access-mtls-authentication-list-mtls-certificates
@@ -212,3 +227,53 @@ func (api *API) DeleteAccessMutualTLSCertificate(ctx context.Context, rc *Resour
 
 	return nil
 }
+
+// GetAccessMutualTLSHostnameSettings returns all Access mTLS hostname settings.
+//
+// Account API Reference: https://developers.cloudflare.com/api/operations/access-mtls-authentication-update-an-mtls-certificate-settings
+// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-mtls-authentication-list-mtls-certificates-hostname-settings
+func (api *API) GetAccessMutualTLSHostnameSettings(ctx context.Context, rc *ResourceContainer) ([]AccessMutualTLSHostnameSettings, error) {
+	uri := fmt.Sprintf(
+		"/%s/%s/access/certificates/settings",
+		rc.Level,
+		rc.Identifier,
+	)
+
+	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
+	if err != nil {
+		return []AccessMutualTLSHostnameSettings{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
+	}
+
+	var accessMutualTLSHostnameSettingsResponse GetAccessMutualTLSHostnameSettingsResponse
+	err = json.Unmarshal(res, &accessMutualTLSHostnameSettingsResponse)
+	if err != nil {
+		return []AccessMutualTLSHostnameSettings{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return accessMutualTLSHostnameSettingsResponse.Result, nil
+}
+
+// UpdateAccessMutualTLSHostnameSettings updates Access mTLS certificate hostname settings.
+//
+// Account API Reference: https://developers.cloudflare.com/api/operations/access-mtls-authentication-update-an-mtls-certificate-settings
+// Zone API Reference: https://developers.cloudflare.com/api/operations/zone-level-access-mtls-authentication-update-an-mtls-certificate-settings
+func (api *API) UpdateAccessMutualTLSHostnameSettings(ctx context.Context, rc *ResourceContainer, params UpdateAccessMutualTLSHostnameSettingsParams) ([]AccessMutualTLSHostnameSettings, error) {
+	uri := fmt.Sprintf(
+		"/%s/%s/access/certificates/settings",
+		rc.Level,
+		rc.Identifier,
+	)
+
+	res, err := api.makeRequestContext(ctx, http.MethodPut, uri, params)
+	if err != nil {
+		return []AccessMutualTLSHostnameSettings{}, fmt.Errorf("%s: %w", errMakeRequestError, err)
+	}
+
+	var accessMutualTLSHostnameSettingsResponse GetAccessMutualTLSHostnameSettingsResponse
+	err = json.Unmarshal(res, &accessMutualTLSHostnameSettingsResponse)
+	if err != nil {
+		return []AccessMutualTLSHostnameSettings{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return accessMutualTLSHostnameSettingsResponse.Result, nil
+}


Test patch:
diff --git a/access_mutual_tls_certificates_test.go b/access_mutual_tls_certificates_test.go
index 235f02134..a83a197da 100644
--- a/access_mutual_tls_certificates_test.go
+++ b/access_mutual_tls_certificates_test.go
@@ -276,3 +276,130 @@ func TestDeleteAccessMutualTLSCertificate(t *testing.T) {
 
 	assert.NoError(t, err)
 }
+
+func TestGetAccessMutualTLSHostnameSettings(t *testing.T) {
+	setup()
+	defer teardown()
+
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method)
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result": [
+				{
+					"china_network": false,
+					"client_certificate_forwarding": true,
+					"hostname": "admin.example.com"
+				},
+				{
+					"china_network": true,
+					"client_certificate_forwarding": false,
+					"hostname": "foobar.example.com"
+				}
+			]
+		}`)
+	}
+
+	want := []AccessMutualTLSHostnameSettings{
+		{
+			ChinaNetwork:                BoolPtr(false),
+			ClientCertificateForwarding: BoolPtr(true),
+			Hostname:                    "admin.example.com",
+		},
+		{
+			ChinaNetwork:                BoolPtr(true),
+			ClientCertificateForwarding: BoolPtr(false),
+			Hostname:                    "foobar.example.com",
+		},
+	}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/access/certificates/settings", handler)
+
+	actual, err := client.GetAccessMutualTLSHostnameSettings(context.Background(), testAccountRC)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+
+	mux.HandleFunc("/zones/"+testZoneID+"/access/certificates/settings", handler)
+
+	actual, err = client.GetAccessMutualTLSHostnameSettings(context.Background(), testZoneRC)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}
+
+func TestUpdateAccessMutualTLSHostnameSettings(t *testing.T) {
+	setup()
+	defer teardown()
+
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method)
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result": [
+				{
+					"china_network": false,
+					"client_certificate_forwarding": true,
+					"hostname": "admin.example.com"
+				},
+				{
+					"china_network": true,
+					"client_certificate_forwarding": false,
+					"hostname": "foobar.example.com"
+				}
+			]
+		}`)
+	}
+
+	certificateSettings := UpdateAccessMutualTLSHostnameSettingsParams{
+		Settings: []AccessMutualTLSHostnameSettings{
+			{
+				ChinaNetwork:                BoolPtr(false),
+				ClientCertificateForwarding: BoolPtr(true),
+				Hostname:                    "admin.example.com",
+			},
+			{
+				ChinaNetwork:                BoolPtr(true),
+				ClientCertificateForwarding: BoolPtr(false),
+				Hostname:                    "foobar.example.com",
+			},
+		},
+	}
+
+	want := []AccessMutualTLSHostnameSettings{
+		{
+			ChinaNetwork:                BoolPtr(false),
+			ClientCertificateForwarding: BoolPtr(true),
+			Hostname:                    "admin.example.com",
+		},
+		{
+			ChinaNetwork:                BoolPtr(true),
+			ClientCertificateForwarding: BoolPtr(false),
+			Hostname:                    "foobar.example.com",
+		},
+	}
+
+	mux.HandleFunc("/accounts/"+testAccountID+"/access/certificates/settings", handler)
+
+	actual, err := client.UpdateAccessMutualTLSHostnameSettings(context.Background(), testAccountRC, certificateSettings)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+
+	mux.HandleFunc("/zones/"+testZoneID+"/access/certificates/settings", handler)
+
+	actual, err = client.UpdateAccessMutualTLSHostnameSettings(context.Background(), testZoneRC, certificateSettings)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}