From c89d7afa55d87074c81cf850d1af18f80a9e8b7d Mon Sep 17 00:00:00 2001 From: vladhanzha Date: Sun, 23 Mar 2025 19:57:02 +0200 Subject: [PATCH 1/4] Add settings support --- cloudconnexa/cloudconnexa.go | 6 +- cloudconnexa/settings.go | 396 +++++++++++++++++++++++++++++++++++ 2 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 cloudconnexa/settings.go diff --git a/cloudconnexa/cloudconnexa.go b/cloudconnexa/cloudconnexa.go index e0ebfae..53c352b 100644 --- a/cloudconnexa/cloudconnexa.go +++ b/cloudconnexa/cloudconnexa.go @@ -43,6 +43,7 @@ type Client struct { VPNRegions *VPNRegionsService LocationContexts *LocationContextsService AccessGroups *AccessGroupsService + Settings *SettingsService } type service struct { @@ -123,6 +124,7 @@ func NewClient(baseURL, clientID, clientSecret string) (*Client, error) { c.VPNRegions = (*VPNRegionsService)(&c.common) c.LocationContexts = (*LocationContextsService)(&c.common) c.AccessGroups = (*AccessGroupsService)(&c.common) + c.Settings = (*SettingsService)(&c.common) return c, nil } @@ -134,7 +136,9 @@ func (c *Client) DoRequest(req *http.Request) ([]byte, error) { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Token)) req.Header.Set("User-Agent", c.UserAgent) - req.Header.Set("Content-Type", "application/json") + if req.Header.Get("Content-Type") == "" { + req.Header.Set("Content-Type", "application/json") + } res, err := c.client.Do(req) if err != nil { diff --git a/cloudconnexa/settings.go b/cloudconnexa/settings.go new file mode 100644 index 0000000..42fdf5e --- /dev/null +++ b/cloudconnexa/settings.go @@ -0,0 +1,396 @@ +package cloudconnexa + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "strconv" +) + +type DnsServers struct { + PrimaryIpV4 string `json:"primaryIpV4,omitempty"` + SecondaryIpV4 string `json:"secondaryIpV4,omitempty"` +} + +type DnsZones struct { + Zones []DnsZone `json:"zones"` +} + +type DnsZone struct { + Name string `json:"name"` + Addresses []string `json:"addresses"` +} + +type DomainRoutingSubnet struct { + IpV4Address string `json:"ipV4Address"` + IpV6Address string `json:"ipV6Address"` +} + +type Subnet struct { + IpV4Address []string `json:"ipV4Address"` + IpV6Address []string `json:"ipV6Address"` +} + +type SettingsService service + +func (c *SettingsService) GetTrustedDevicesAllowed() (bool, error) { + return c.getBool("/auth/trusted-devices-allowed") +} + +func (c *SettingsService) SetTrustedDevicesAllowed(value bool) (bool, error) { + return c.setBool("/auth/trusted-devices-allowed", value) +} + +func (c *SettingsService) GetTwoFactorAuthEnabled() (bool, error) { + return c.getBool("/auth/two-factor-auth") +} + +func (c *SettingsService) SetTwoFactorAuthEnabled(value bool) (bool, error) { + return c.setBool("/auth/two-factor-auth", value) +} + +func (c *SettingsService) GetDnsServers() (*DnsServers, error) { + body, err := c.get("/dns/custom-servers") + if err != nil { + return nil, err + } + + var response DnsServers + s := string(body) + if s == "" { + return nil, nil + } + + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return &response, nil +} + +func (c *SettingsService) SetDnsServers(value *DnsServers) (*DnsServers, error) { + jsonValue, err := json.Marshal(value) + if err != nil { + return nil, err + } + body, err := c.set("/dns/custom-servers", jsonValue) + if err != nil { + return nil, err + } + var response DnsServers + s := string(body) + if s == "" { + return nil, nil + } + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return &response, nil +} + +func (c *SettingsService) GetDefaultDnsSuffix() (string, error) { + return c.getString("/dns/default-suffix") +} + +func (c *SettingsService) SetDefaultDnsSuffix(value string) (string, error) { + return c.setString("/dns/default-suffix", value) +} + +func (c *SettingsService) GetDnsProxyEnabled() (bool, error) { + return c.getBool("/dns/proxy-enabled") +} + +func (c *SettingsService) SetDnsProxyAuthEnabled(value bool) (bool, error) { + return c.setBool("/dns/proxy-enabled", value) +} + +func (c *SettingsService) GetDnsZones() ([]DnsZone, error) { + body, err := c.get("/dns/zones") + if err != nil { + return nil, err + } + + var response DnsZones + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return response.Zones, nil +} + +func (c *SettingsService) SetDnsZones(value []DnsZone) ([]DnsZone, error) { + jsonValue, err := json.Marshal(value) + if err != nil { + return nil, err + } + body, err := c.set("/dns/zones", jsonValue) + if err != nil { + return nil, err + } + var response DnsZones + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return response.Zones, nil +} + +func (c *SettingsService) GetDefaultConnectAuth() (string, error) { + return c.getString("/user/connect-auth") +} + +func (c *SettingsService) SetDefaultConnectAuth(value string) (string, error) { + return c.setString("/user/connect-auth", value) +} + +func (c *SettingsService) GetDefaultDeviceAllowancePerUser() (int, error) { + return c.getInt("/user/device-allowance") +} + +func (c *SettingsService) SetDefaultDeviceAllowancePerUser(value int) (int, error) { + return c.setInt("/user/device-allowance", value) +} + +func (c *SettingsService) GetForceUpdateDeviceAllowanceEnabled() (bool, error) { + return c.getBool("/user/device-allowance-force-update") +} + +func (c *SettingsService) SetForceUpdateDeviceAllowanceEnabled(value bool) (bool, error) { + return c.setBool("/user/device-allowance-force-update", value) +} + +func (c *SettingsService) GetDeviceEnforcement() (string, error) { + return c.getString("/user/device-enforcement") +} + +func (c *SettingsService) SetDeviceEnforcement(value string) (string, error) { + return c.setString("/user/device-enforcement", value) +} + +func (c *SettingsService) GetProfileDistribution() (string, error) { + return c.getString("/user/profile-distribution") +} + +func (c *SettingsService) SetProfileDistribution(value string) (string, error) { + return c.setString("/user/profile-distribution", value) +} + +func (c *SettingsService) GetConnectionTimeout() (int, error) { + return c.getInt("/users/connection-timeout") +} + +func (c *SettingsService) SetConnectionTimeout(value int) (int, error) { + return c.setInt("/users/connection-timeout", value) +} + +func (c *SettingsService) GetClientOptions() ([]string, error) { + body, err := c.get("/wpc/client-options") + if err != nil { + return nil, err + } + + var response []string + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return response, nil +} + +func (c *SettingsService) SetClientOptions(value []string) ([]string, error) { + jsonValue, err := json.Marshal(value) + if err != nil { + return nil, err + } + body, err := c.set("/wpc/client-options", jsonValue) + if err != nil { + return nil, err + } + var response []string + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return response, nil +} + +func (c *SettingsService) GetDefaultRegion() (string, error) { + return c.getString("/wpc/default-region") +} + +func (c *SettingsService) SetDefaultRegion(value string) (string, error) { + return c.setString("/wpc/default-region", value) +} + +func (c *SettingsService) GetDomainRoutingSubnet() (*DomainRoutingSubnet, error) { + body, err := c.get("/wpc/domain-routing-subnet") + if err != nil { + return nil, err + } + + var response DomainRoutingSubnet + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return &response, nil +} + +func (c *SettingsService) SetDomainRoutingSubnet(value DomainRoutingSubnet) (*DomainRoutingSubnet, error) { + jsonValue, err := json.Marshal(value) + if err != nil { + return nil, err + } + body, err := c.set("/wpc/domain-routing-subnet", jsonValue) + if err != nil { + return nil, err + } + var response DomainRoutingSubnet + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return &response, nil +} + +func (c *SettingsService) GetSnatEnabled() (bool, error) { + return c.getBool("/wpc/snat") +} + +func (c *SettingsService) SetSnatEnabled(value bool) (bool, error) { + return c.setBool("/wpc/snat", value) +} + +func (c *SettingsService) GetSubnet() (*Subnet, error) { + body, err := c.get("/wpc/subnet") + if err != nil { + return nil, err + } + + var response Subnet + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return &response, nil +} + +func (c *SettingsService) SetSubnet(value Subnet) (*Subnet, error) { + jsonValue, err := json.Marshal(value) + if err != nil { + return nil, err + } + body, err := c.set("/wpc/subnet", jsonValue) + if err != nil { + return nil, err + } + var response Subnet + err = json.Unmarshal(body, &response) + if err != nil { + return nil, err + } + return &response, nil +} + +func (c *SettingsService) GetTopology() (string, error) { + return c.getString("/wpc/topology") +} + +func (c *SettingsService) SetTopology(value string) (string, error) { + return c.setString("/wpc/topology", value) +} + +func (c *SettingsService) getBool(path string) (bool, error) { + body, err := c.get(path) + if err != nil { + return false, err + } + + var response bool + err = json.Unmarshal(body, &response) + if err != nil { + return false, err + } + return response, nil +} + +func (c *SettingsService) setBool(path string, value bool) (bool, error) { + body, err := c.set(path, []byte(strconv.FormatBool(value))) + var response bool + err = json.Unmarshal(body, &response) + if err != nil { + return false, err + } + return response, nil +} + +func (c *SettingsService) getString(path string) (string, error) { + endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) + req, err := http.NewRequest(http.MethodGet, endpoint, nil) + if err != nil { + return "", err + } + body, err := c.client.DoRequest(req) + if err != nil { + return "", err + } + return string(body), nil +} + +func (c *SettingsService) setString(path string, value string) (string, error) { + endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) + req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer([]byte(value))) + req.Header.Set("Content-Type", "text/plain") + if err != nil { + return "", err + } + body, err := c.client.DoRequest(req) + if err != nil { + return "", err + } + return string(body), nil +} + +func (c *SettingsService) getInt(path string) (int, error) { + body, err := c.get(path) + if err != nil { + return 0, err + } + return strconv.Atoi(string(body)) +} + +func (c *SettingsService) setInt(path string, value int) (int, error) { + body, err := c.set(path, []byte(strconv.Itoa(value))) + if err != nil { + return 0, err + } + return strconv.Atoi(string(body)) +} + +func (c *SettingsService) get(path string) ([]byte, error) { + endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) + req, err := http.NewRequest(http.MethodGet, endpoint, nil) + if err != nil { + return nil, err + } + body, err := c.client.DoRequest(req) + if err != nil { + return nil, err + } + return body, nil +} + +func (c *SettingsService) set(path string, value []byte) ([]byte, error) { + endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) + req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer(value)) + if err != nil { + return nil, err + } + body, err := c.client.DoRequest(req) + if err != nil { + return nil, err + } + return body, nil +} From e0e3231c0d4a8ad2194481112d8dc3428dfd7776 Mon Sep 17 00:00:00 2001 From: vladhanzha Date: Sun, 13 Apr 2025 11:53:44 +0300 Subject: [PATCH 2/4] Fix lint issues --- cloudconnexa/settings.go | 47 +++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/cloudconnexa/settings.go b/cloudconnexa/settings.go index 42fdf5e..93f7c39 100644 --- a/cloudconnexa/settings.go +++ b/cloudconnexa/settings.go @@ -8,28 +8,28 @@ import ( "strconv" ) -type DnsServers struct { - PrimaryIpV4 string `json:"primaryIpV4,omitempty"` - SecondaryIpV4 string `json:"secondaryIpV4,omitempty"` +type DNSServers struct { + PrimaryIPV4 string `json:"primaryIpV4,omitempty"` + SecondaryIPV4 string `json:"secondaryIpV4,omitempty"` } -type DnsZones struct { - Zones []DnsZone `json:"zones"` +type DNSZones struct { + Zones []DNSZone `json:"zones"` } -type DnsZone struct { +type DNSZone struct { Name string `json:"name"` Addresses []string `json:"addresses"` } type DomainRoutingSubnet struct { - IpV4Address string `json:"ipV4Address"` - IpV6Address string `json:"ipV6Address"` + IPV4Address string `json:"ipV4Address"` + IPV6Address string `json:"ipV6Address"` } type Subnet struct { - IpV4Address []string `json:"ipV4Address"` - IpV6Address []string `json:"ipV6Address"` + IPV4Address []string `json:"ipV4Address"` + IPV6Address []string `json:"ipV6Address"` } type SettingsService service @@ -50,13 +50,13 @@ func (c *SettingsService) SetTwoFactorAuthEnabled(value bool) (bool, error) { return c.setBool("/auth/two-factor-auth", value) } -func (c *SettingsService) GetDnsServers() (*DnsServers, error) { +func (c *SettingsService) GetDNSServers() (*DNSServers, error) { body, err := c.get("/dns/custom-servers") if err != nil { return nil, err } - var response DnsServers + var response DNSServers s := string(body) if s == "" { return nil, nil @@ -69,7 +69,7 @@ func (c *SettingsService) GetDnsServers() (*DnsServers, error) { return &response, nil } -func (c *SettingsService) SetDnsServers(value *DnsServers) (*DnsServers, error) { +func (c *SettingsService) SetDNSServers(value *DNSServers) (*DNSServers, error) { jsonValue, err := json.Marshal(value) if err != nil { return nil, err @@ -78,7 +78,7 @@ func (c *SettingsService) SetDnsServers(value *DnsServers) (*DnsServers, error) if err != nil { return nil, err } - var response DnsServers + var response DNSServers s := string(body) if s == "" { return nil, nil @@ -90,29 +90,29 @@ func (c *SettingsService) SetDnsServers(value *DnsServers) (*DnsServers, error) return &response, nil } -func (c *SettingsService) GetDefaultDnsSuffix() (string, error) { +func (c *SettingsService) GetDefaultDNSSuffix() (string, error) { return c.getString("/dns/default-suffix") } -func (c *SettingsService) SetDefaultDnsSuffix(value string) (string, error) { +func (c *SettingsService) SetDefaultDNSSuffix(value string) (string, error) { return c.setString("/dns/default-suffix", value) } -func (c *SettingsService) GetDnsProxyEnabled() (bool, error) { +func (c *SettingsService) GetDNSProxyEnabled() (bool, error) { return c.getBool("/dns/proxy-enabled") } -func (c *SettingsService) SetDnsProxyAuthEnabled(value bool) (bool, error) { +func (c *SettingsService) SetDNSProxyEnabled(value bool) (bool, error) { return c.setBool("/dns/proxy-enabled", value) } -func (c *SettingsService) GetDnsZones() ([]DnsZone, error) { +func (c *SettingsService) GetDNSZones() ([]DNSZone, error) { body, err := c.get("/dns/zones") if err != nil { return nil, err } - var response DnsZones + var response DNSZones err = json.Unmarshal(body, &response) if err != nil { return nil, err @@ -120,7 +120,7 @@ func (c *SettingsService) GetDnsZones() ([]DnsZone, error) { return response.Zones, nil } -func (c *SettingsService) SetDnsZones(value []DnsZone) ([]DnsZone, error) { +func (c *SettingsService) SetDNSZones(value []DNSZone) ([]DNSZone, error) { jsonValue, err := json.Marshal(value) if err != nil { return nil, err @@ -129,7 +129,7 @@ func (c *SettingsService) SetDnsZones(value []DnsZone) ([]DnsZone, error) { if err != nil { return nil, err } - var response DnsZones + var response DNSZones err = json.Unmarshal(body, &response) if err != nil { return nil, err @@ -318,6 +318,9 @@ func (c *SettingsService) getBool(path string) (bool, error) { func (c *SettingsService) setBool(path string, value bool) (bool, error) { body, err := c.set(path, []byte(strconv.FormatBool(value))) + if err != nil { + return false, err + } var response bool err = json.Unmarshal(body, &response) if err != nil { From 9830a5c1b9a72b1df8b83a8d988454e54565dcf8 Mon Sep 17 00:00:00 2001 From: Denis Arslanbekov Date: Fri, 6 Jun 2025 15:12:33 +0100 Subject: [PATCH 3/4] Add DNS and user settings management functions Signed-off-by: Denis Arslanbekov --- cloudconnexa/settings.go | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/cloudconnexa/settings.go b/cloudconnexa/settings.go index 93f7c39..b1164ae 100644 --- a/cloudconnexa/settings.go +++ b/cloudconnexa/settings.go @@ -8,48 +8,59 @@ import ( "strconv" ) +// DNSServers represents DNS server configuration with primary and secondary IPv4 addresses type DNSServers struct { PrimaryIPV4 string `json:"primaryIpV4,omitempty"` SecondaryIPV4 string `json:"secondaryIpV4,omitempty"` } +// DNSZones represents a collection of DNS zones type DNSZones struct { Zones []DNSZone `json:"zones"` } +// DNSZone represents a single DNS zone with name and associated addresses type DNSZone struct { Name string `json:"name"` Addresses []string `json:"addresses"` } +// DomainRoutingSubnet represents subnet configuration for domain routing with IPv4 and IPv6 addresses type DomainRoutingSubnet struct { IPV4Address string `json:"ipV4Address"` IPV6Address string `json:"ipV6Address"` } +// Subnet represents network subnet configuration with IPv4 and IPv6 address ranges type Subnet struct { IPV4Address []string `json:"ipV4Address"` IPV6Address []string `json:"ipV6Address"` } +// SettingsService handles operations related to system settings type SettingsService service +// GetTrustedDevicesAllowed retrieves whether trusted devices are allowed func (c *SettingsService) GetTrustedDevicesAllowed() (bool, error) { return c.getBool("/auth/trusted-devices-allowed") } +// SetTrustedDevicesAllowed sets whether trusted devices are allowed func (c *SettingsService) SetTrustedDevicesAllowed(value bool) (bool, error) { return c.setBool("/auth/trusted-devices-allowed", value) } +// GetTwoFactorAuthEnabled retrieves whether two-factor authentication is enabled func (c *SettingsService) GetTwoFactorAuthEnabled() (bool, error) { return c.getBool("/auth/two-factor-auth") } +// SetTwoFactorAuthEnabled sets whether two-factor authentication is enabled func (c *SettingsService) SetTwoFactorAuthEnabled(value bool) (bool, error) { return c.setBool("/auth/two-factor-auth", value) } +// GetDNSServers retrieves the current DNS server configuration func (c *SettingsService) GetDNSServers() (*DNSServers, error) { body, err := c.get("/dns/custom-servers") if err != nil { @@ -69,6 +80,7 @@ func (c *SettingsService) GetDNSServers() (*DNSServers, error) { return &response, nil } +// SetDNSServers updates the DNS server configuration func (c *SettingsService) SetDNSServers(value *DNSServers) (*DNSServers, error) { jsonValue, err := json.Marshal(value) if err != nil { @@ -90,22 +102,27 @@ func (c *SettingsService) SetDNSServers(value *DNSServers) (*DNSServers, error) return &response, nil } +// GetDefaultDNSSuffix retrieves the default DNS suffix func (c *SettingsService) GetDefaultDNSSuffix() (string, error) { return c.getString("/dns/default-suffix") } +// SetDefaultDNSSuffix sets the default DNS suffix func (c *SettingsService) SetDefaultDNSSuffix(value string) (string, error) { return c.setString("/dns/default-suffix", value) } +// GetDNSProxyEnabled retrieves whether DNS proxy is enabled func (c *SettingsService) GetDNSProxyEnabled() (bool, error) { return c.getBool("/dns/proxy-enabled") } +// SetDNSProxyEnabled sets whether DNS proxy is enabled func (c *SettingsService) SetDNSProxyEnabled(value bool) (bool, error) { return c.setBool("/dns/proxy-enabled", value) } +// GetDNSZones retrieves the current DNS zones configuration func (c *SettingsService) GetDNSZones() ([]DNSZone, error) { body, err := c.get("/dns/zones") if err != nil { @@ -120,6 +137,7 @@ func (c *SettingsService) GetDNSZones() ([]DNSZone, error) { return response.Zones, nil } +// SetDNSZones updates the DNS zones configuration func (c *SettingsService) SetDNSZones(value []DNSZone) ([]DNSZone, error) { jsonValue, err := json.Marshal(value) if err != nil { @@ -137,54 +155,67 @@ func (c *SettingsService) SetDNSZones(value []DNSZone) ([]DNSZone, error) { return response.Zones, nil } +// GetDefaultConnectAuth retrieves the default connection authentication method func (c *SettingsService) GetDefaultConnectAuth() (string, error) { return c.getString("/user/connect-auth") } +// SetDefaultConnectAuth sets the default connection authentication method func (c *SettingsService) SetDefaultConnectAuth(value string) (string, error) { return c.setString("/user/connect-auth", value) } +// GetDefaultDeviceAllowancePerUser retrieves the default device allowance per user func (c *SettingsService) GetDefaultDeviceAllowancePerUser() (int, error) { return c.getInt("/user/device-allowance") } +// SetDefaultDeviceAllowancePerUser sets the default device allowance per user func (c *SettingsService) SetDefaultDeviceAllowancePerUser(value int) (int, error) { return c.setInt("/user/device-allowance", value) } +// GetForceUpdateDeviceAllowanceEnabled retrieves whether force update device allowance is enabled func (c *SettingsService) GetForceUpdateDeviceAllowanceEnabled() (bool, error) { return c.getBool("/user/device-allowance-force-update") } +// SetForceUpdateDeviceAllowanceEnabled sets whether force update device allowance is enabled func (c *SettingsService) SetForceUpdateDeviceAllowanceEnabled(value bool) (bool, error) { return c.setBool("/user/device-allowance-force-update", value) } +// GetDeviceEnforcement retrieves the device enforcement policy func (c *SettingsService) GetDeviceEnforcement() (string, error) { return c.getString("/user/device-enforcement") } +// SetDeviceEnforcement sets the device enforcement policy func (c *SettingsService) SetDeviceEnforcement(value string) (string, error) { return c.setString("/user/device-enforcement", value) } +// GetProfileDistribution retrieves the profile distribution method func (c *SettingsService) GetProfileDistribution() (string, error) { return c.getString("/user/profile-distribution") } +// SetProfileDistribution sets the profile distribution method func (c *SettingsService) SetProfileDistribution(value string) (string, error) { return c.setString("/user/profile-distribution", value) } +// GetConnectionTimeout retrieves the connection timeout value func (c *SettingsService) GetConnectionTimeout() (int, error) { return c.getInt("/users/connection-timeout") } +// SetConnectionTimeout sets the connection timeout value func (c *SettingsService) SetConnectionTimeout(value int) (int, error) { return c.setInt("/users/connection-timeout", value) } +// GetClientOptions retrieves the client options configuration func (c *SettingsService) GetClientOptions() ([]string, error) { body, err := c.get("/wpc/client-options") if err != nil { @@ -199,6 +230,7 @@ func (c *SettingsService) GetClientOptions() ([]string, error) { return response, nil } +// SetClientOptions updates the client options configuration func (c *SettingsService) SetClientOptions(value []string) ([]string, error) { jsonValue, err := json.Marshal(value) if err != nil { @@ -216,14 +248,17 @@ func (c *SettingsService) SetClientOptions(value []string) ([]string, error) { return response, nil } +// GetDefaultRegion retrieves the default region setting func (c *SettingsService) GetDefaultRegion() (string, error) { return c.getString("/wpc/default-region") } +// SetDefaultRegion sets the default region func (c *SettingsService) SetDefaultRegion(value string) (string, error) { return c.setString("/wpc/default-region", value) } +// GetDomainRoutingSubnet retrieves the domain routing subnet configuration func (c *SettingsService) GetDomainRoutingSubnet() (*DomainRoutingSubnet, error) { body, err := c.get("/wpc/domain-routing-subnet") if err != nil { @@ -238,6 +273,7 @@ func (c *SettingsService) GetDomainRoutingSubnet() (*DomainRoutingSubnet, error) return &response, nil } +// SetDomainRoutingSubnet updates the domain routing subnet configuration func (c *SettingsService) SetDomainRoutingSubnet(value DomainRoutingSubnet) (*DomainRoutingSubnet, error) { jsonValue, err := json.Marshal(value) if err != nil { @@ -255,14 +291,17 @@ func (c *SettingsService) SetDomainRoutingSubnet(value DomainRoutingSubnet) (*Do return &response, nil } +// GetSnatEnabled retrieves whether SNAT is enabled func (c *SettingsService) GetSnatEnabled() (bool, error) { return c.getBool("/wpc/snat") } +// SetSnatEnabled sets whether SNAT is enabled func (c *SettingsService) SetSnatEnabled(value bool) (bool, error) { return c.setBool("/wpc/snat", value) } +// GetSubnet retrieves the subnet configuration func (c *SettingsService) GetSubnet() (*Subnet, error) { body, err := c.get("/wpc/subnet") if err != nil { @@ -277,6 +316,7 @@ func (c *SettingsService) GetSubnet() (*Subnet, error) { return &response, nil } +// SetSubnet updates the subnet configuration func (c *SettingsService) SetSubnet(value Subnet) (*Subnet, error) { jsonValue, err := json.Marshal(value) if err != nil { @@ -294,14 +334,17 @@ func (c *SettingsService) SetSubnet(value Subnet) (*Subnet, error) { return &response, nil } +// GetTopology retrieves the network topology setting func (c *SettingsService) GetTopology() (string, error) { return c.getString("/wpc/topology") } +// SetTopology sets the network topology func (c *SettingsService) SetTopology(value string) (string, error) { return c.setString("/wpc/topology", value) } +// getBool retrieves a boolean value from the specified path func (c *SettingsService) getBool(path string) (bool, error) { body, err := c.get(path) if err != nil { @@ -316,6 +359,7 @@ func (c *SettingsService) getBool(path string) (bool, error) { return response, nil } +// setBool sets a boolean value at the specified path func (c *SettingsService) setBool(path string, value bool) (bool, error) { body, err := c.set(path, []byte(strconv.FormatBool(value))) if err != nil { @@ -329,6 +373,7 @@ func (c *SettingsService) setBool(path string, value bool) (bool, error) { return response, nil } +// getString retrieves a string value from the specified path func (c *SettingsService) getString(path string) (string, error) { endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) req, err := http.NewRequest(http.MethodGet, endpoint, nil) @@ -342,6 +387,7 @@ func (c *SettingsService) getString(path string) (string, error) { return string(body), nil } +// setString sets a string value at the specified path func (c *SettingsService) setString(path string, value string) (string, error) { endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer([]byte(value))) @@ -356,6 +402,7 @@ func (c *SettingsService) setString(path string, value string) (string, error) { return string(body), nil } +// getInt retrieves an integer value from the specified path func (c *SettingsService) getInt(path string) (int, error) { body, err := c.get(path) if err != nil { @@ -364,6 +411,7 @@ func (c *SettingsService) getInt(path string) (int, error) { return strconv.Atoi(string(body)) } +// setInt sets an integer value at the specified path func (c *SettingsService) setInt(path string, value int) (int, error) { body, err := c.set(path, []byte(strconv.Itoa(value))) if err != nil { @@ -372,6 +420,7 @@ func (c *SettingsService) setInt(path string, value int) (int, error) { return strconv.Atoi(string(body)) } +// get performs a GET request to the specified path func (c *SettingsService) get(path string) ([]byte, error) { endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) req, err := http.NewRequest(http.MethodGet, endpoint, nil) @@ -385,6 +434,7 @@ func (c *SettingsService) get(path string) ([]byte, error) { return body, nil } +// set performs a PUT request to the specified path with the given value func (c *SettingsService) set(path string, value []byte) ([]byte, error) { endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer(value)) From 609ec086abc718a7b1f3071753206f0e83a159c9 Mon Sep 17 00:00:00 2001 From: Denis Arslanbekov Date: Fri, 6 Jun 2025 15:28:39 +0100 Subject: [PATCH 4/4] Refactor HTTP header setting logic into reusable helper function - Add setCommonHeaders helper to centralize Authorization, User-Agent, and Content-Type header logic - Improve maintainability by reducing code duplication across HTTP requests - Preserve existing behavior while enhancing code organization --- cloudconnexa/cloudconnexa.go | 18 +++++++++++++----- cloudconnexa/settings.go | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cloudconnexa/cloudconnexa.go b/cloudconnexa/cloudconnexa.go index 5e869dd..f50ef3b 100644 --- a/cloudconnexa/cloudconnexa.go +++ b/cloudconnexa/cloudconnexa.go @@ -139,6 +139,18 @@ func NewClient(baseURL, clientID, clientSecret string) (*Client, error) { return c, nil } +// setCommonHeaders sets the standard headers for API requests. +// It sets Authorization and User-Agent headers, and sets Content-Type to application/json +// if no Content-Type header is already present. +func (c *Client) setCommonHeaders(req *http.Request) { + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Token)) + req.Header.Set("User-Agent", c.UserAgent) + + if req.Header.Get("Content-Type") == "" { + req.Header.Set("Content-Type", "application/json") + } +} + // DoRequest executes an HTTP request with authentication and rate limiting. // It automatically adds the Bearer token, sets headers, and handles errors. func (c *Client) DoRequest(req *http.Request) ([]byte, error) { @@ -147,11 +159,7 @@ func (c *Client) DoRequest(req *http.Request) ([]byte, error) { return nil, err } - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Token)) - req.Header.Set("User-Agent", c.UserAgent) - if req.Header.Get("Content-Type") == "" { - req.Header.Set("Content-Type", "application/json") - } + c.setCommonHeaders(req) res, err := c.client.Do(req) if err != nil { diff --git a/cloudconnexa/settings.go b/cloudconnexa/settings.go index b1164ae..a14a0bf 100644 --- a/cloudconnexa/settings.go +++ b/cloudconnexa/settings.go @@ -391,10 +391,10 @@ func (c *SettingsService) getString(path string) (string, error) { func (c *SettingsService) setString(path string, value string) (string, error) { endpoint := fmt.Sprintf("%s/settings"+path, c.client.GetV1Url()) req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer([]byte(value))) - req.Header.Set("Content-Type", "text/plain") if err != nil { return "", err } + req.Header.Set("Content-Type", "text/plain") body, err := c.client.DoRequest(req) if err != nil { return "", err