Files
unifi-network-operator/internal/unifi/unifi.go
Vegard Engen 8765a94893
Some checks failed
Lint / Run on Ubuntu (push) Failing after 7s
E2E Tests / Run on Ubuntu (push) Failing after 3s
Tests / Run on Ubuntu (push) Failing after 3s
Rename
2025-06-24 00:12:16 +02:00

127 lines
2.8 KiB
Go

/* https://github.com/clbx/kube-port-forward-controller */
package unifi
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net/http"
"net/http/cookiejar"
"os"
"strings"
"sync"
"gitea.engen.priv.no/klauvsteinen/go-unifi/unifi"
)
type UnifiClient struct {
Client *unifi.Client
SiteID string
mutex sync.Mutex
controller string
username string
password string
}
func CreateUnifiClient() (*UnifiClient, error) {
client := &unifi.Client{}
unifiURL := os.Getenv("UNIFI_URL")
if unifiURL == "" {
return nil, errors.New("could not get UniFi URL from environment variables")
}
siteID := os.Getenv("UNIFI_SITE")
if siteID == "" {
return nil, errors.New("could not get UniFi site ID from environment variables")
}
username := os.Getenv("UNIFI_USER")
if username == "" {
return nil, errors.New("could not get UniFi username from environment variables")
}
password := os.Getenv("UNIFI_PASSWORD")
if password == "" {
return nil, errors.New("could not get UniFi password from environment variables")
}
if err := client.SetBaseURL(unifiURL); err != nil {
return nil, err
}
jar, _ := cookiejar.New(nil)
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
httpClient := &http.Client{
Jar: jar,
Transport: tr,
}
if err := client.SetHTTPClient(httpClient); err != nil {
return nil, fmt.Errorf("failed to set HTTP client: %s", err)
}
if err := client.Login(context.Background(), username, password); err != nil {
return nil, fmt.Errorf("could not log into UniFi controller: %s", err)
}
unifiClient := &UnifiClient{
Client: client,
SiteID: siteID,
controller: unifiURL,
username: username,
password: password,
}
return unifiClient, nil
}
func (s *UnifiClient) WithSession(action func(c *unifi.Client) error) error {
s.mutex.Lock()
defer s.mutex.Unlock()
err := action(s.Client)
if err == nil {
return nil
}
if IsSessionExpired(err) {
if loginErr := s.Client.Login(context.Background(), s.username, s.password); loginErr != nil {
return fmt.Errorf("re-login to Unifi failed: %w", loginErr)
}
return action(s.Client)
}
return err
}
func (uClient *UnifiClient) Reauthenticate() error {
_, err := uClient.Client.ListSites(context.Background())
if err == nil {
return nil
}
if IsSessionExpired(err) {
if loginErr := uClient.Client.Login(context.Background(), uClient.username, uClient.password); loginErr != nil {
return fmt.Errorf("re-login to Unifi failed: %w", loginErr)
}
}
return nil
}
func IsSessionExpired(err error) bool {
if err == nil {
return false
}
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "unauthorized") ||
strings.Contains(msg, "authentication") ||
strings.Contains(msg, "login required") ||
strings.Contains(msg, "token")
}