package v1 import ( "context" "crypto/tls" "errors" "fmt" "github.com/filipowm/terraform-provider-unifi/internal/provider" "net" "net/http" "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func init() { schema.DescriptionKind = schema.StringMarkdown schema.SchemaDescriptionBuilder = func(s *schema.Schema) string { desc := s.Description if s.Default != nil { desc += fmt.Sprintf(" Defaults to `%v`.", s.Default) } if s.Deprecated != "" { desc += " " + s.Deprecated } return strings.TrimSpace(desc) } } func New(version string) func() *schema.Provider { return func() *schema.Provider { p := &schema.Provider{ Schema: map[string]*schema.Schema{ "username": { Description: provider.ProviderUsernameDescription, Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_USERNAME", ""), }, "password": { Description: provider.ProviderPasswordDescription, Type: schema.TypeString, Optional: true, Sensitive: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_PASSWORD", ""), }, "api_key": { Description: provider.ProviderAPIKeyDescription, Type: schema.TypeString, Optional: true, Sensitive: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_API_KEY", ""), }, "api_url": { Description: provider.ProviderAPIURLDescription, Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_API", ""), }, "site": { Description: provider.ProviderSiteDescription, Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_SITE", "default"), }, "allow_insecure": { Description: provider.ProviderAllowInsecureDescription, Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("UNIFI_INSECURE", false), }, }, DataSourcesMap: map[string]*schema.Resource{ "unifi_ap_group": dataAPGroup(), "unifi_network": dataNetwork(), "unifi_port_profile": dataPortProfile(), "unifi_radius_profile": dataRADIUSProfile(), "unifi_user_group": dataUserGroup(), "unifi_user": dataUser(), "unifi_account": dataAccount(), }, ResourcesMap: map[string]*schema.Resource{ // TODO: "unifi_ap_group" "unifi_device": resourceDevice(), "unifi_dynamic_dns": resourceDynamicDNS(), "unifi_firewall_group": resourceFirewallGroup(), "unifi_firewall_rule": resourceFirewallRule(), "unifi_network": resourceNetwork(), "unifi_port_forward": resourcePortForward(), "unifi_port_profile": resourcePortProfile(), "unifi_radius_profile": resourceRadiusProfile(), "unifi_site": resourceSite(), "unifi_static_route": resourceStaticRoute(), "unifi_user_group": resourceUserGroup(), "unifi_user": resourceUser(), "unifi_wlan": resourceWLAN(), "unifi_account": resourceAccount(), "unifi_setting_mgmt": resourceSettingMgmt(), "unifi_setting_radius": resourceSettingRadius(), "unifi_setting_usg": resourceSettingUsg(), }, } p.ConfigureContextFunc = configure(version, p) return p } } func createHTTPTransport(insecure bool, subsystem string) http.RoundTripper { transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, DualStack: true, }).DialContext, MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, TLSClientConfig: &tls.Config{ InsecureSkipVerify: insecure, }, } t := logging.NewSubsystemLoggingHTTPTransport(subsystem, transport) return t } func configure(v string, p *schema.Provider) schema.ConfigureContextFunc { return func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { user := d.Get("username").(string) pass := d.Get("password").(string) apiKey := d.Get("api_key").(string) if apiKey != "" && (user != "" || pass != "") { return nil, diag.FromErr(errors.New("only one of `username`/`password` or `api_key` can be set")) } else if apiKey == "" && (user == "" || pass == "") { return nil, diag.FromErr(errors.New("either `username` and `password` or `api_key` must be set")) } baseURL := d.Get("api_url").(string) site := d.Get("site").(string) insecure := d.Get("allow_insecure").(bool) c, err := provider.NewClient(&provider.ClientConfig{ Username: user, Password: pass, ApiKey: apiKey, Url: baseURL, Site: site, HttpConfigurer: func() http.RoundTripper { return createHTTPTransport(insecure, "unifi") }, }) if err != nil { return nil, diag.FromErr(err) } return c, nil } }