Files
terraform-provider-unifi/internal/provider/base/client.go
Mateusz Filipowicz e9600c6e06 feat: add support for Intrution Prevention System (IPS) settings with unifi_setting_ips resource (#56)
* feat: add support for Intrution Prevention System (IPS) settings with `unifi_setting_ips` resource

* require IPS features enabled on controller

* require version 7.4

* require version 7.5 for advanced_filtering_preference

* feat: use Remember Me to prolong session for user/pass authentication

* run some setting mgmt tests on 7.0+ due to auto_upgrade_hour not working until device is adopted and auto upgrade logic is different and not supported
2025-03-16 12:53:46 +01:00

120 lines
3.0 KiB
Go

package base
import (
"context"
"crypto/tls"
"fmt"
"github.com/filipowm/go-unifi/unifi"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"log"
"net"
"net/http"
"time"
)
type ClientConfig struct {
Username string
Password string
ApiKey string
Url string
Site string
Insecure bool
HttpConfigurer func() http.RoundTripper
}
func NewClient(cfg *ClientConfig) (*Client, error) {
config := &unifi.ClientConfig{
URL: cfg.Url,
User: cfg.Username,
Password: cfg.Password,
APIKey: cfg.ApiKey,
HttpRoundTripperProvider: cfg.HttpConfigurer,
ValidationMode: unifi.DisableValidation,
Logger: unifi.NewDefaultLogger(unifi.WarnLevel),
}
if cfg.Username != "" && cfg.Password != "" {
config.User = cfg.Username
config.Password = cfg.Password
config.RememberMe = true
} else {
config.APIKey = cfg.ApiKey
}
unifiClient, err := unifi.NewClient(config)
if err != nil {
return nil, err
}
err = CheckMinimumControllerVersion(unifiClient.Version())
log.Printf("[TRACE] Unifi controller version: %q", unifiClient.Version())
if err != nil {
return nil, err
}
c := &Client{
Client: unifiClient,
Site: cfg.Site,
Version: version.Must(version.NewVersion(unifiClient.Version())),
}
if cfg.ApiKey != "" && !c.SupportsApiKeyAuthentication() {
return nil, fmt.Errorf("API key authentication is not supported on this controller version: %s, you must be on %s or higher", c.Version, ControllerVersionApiKeyAuth)
}
return c, nil
}
type Client struct {
unifi.Client
Site string
Version *version.Version
}
func (c *Client) ResolveSite(res SiteAware) string {
if res == nil || IsEmptyString(res.GetRawSite()) {
return c.Site
}
return res.GetSite()
}
func (c *Client) ResolveSiteFromConfig(ctx context.Context, config tfsdk.Config) (string, diag.Diagnostics) {
var site types.String
diags := config.GetAttribute(ctx, path.Root("site"), &site)
if diags.HasError() {
return "", diags
}
if IsEmptyString(site) {
return c.Site, diags
}
return site.ValueString(), diags
}
func CreateHttpTransport(insecure bool) http.RoundTripper {
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: insecure,
},
}
}
func checkClientConfigured(client *Client) diag.Diagnostics {
diags := diag.Diagnostics{}
if client == nil {
diags.AddError(
"Client Not Configured",
"Expected configured client. Please report this issue to the provider developers.",
)
}
return diags
}