diff --git a/client.go b/client.go index 0357e39..ed9c4d4 100644 --- a/client.go +++ b/client.go @@ -38,10 +38,10 @@ func ExponentialBackoff(b float64, d time.Duration) BackoffFunc { type Client struct { sync.Mutex - endpoint string - username string - password string - session session + endpoints []string + username string + password string + session session //pollInterval time.Duration //backoffFunc BackoffFunc httpClient *http.Client @@ -66,7 +66,15 @@ type ClientOption func(*Client) func WithEndpoint(endpoint string) ClientOption { return func(client *Client) { - client.endpoint = strings.TrimRight(endpoint, "/") + client.endpoints = append(client.endpoints, strings.TrimRight(endpoint, "/")) + } +} + +func WithEndpoints(endpoints []string) ClientOption { + return func(client *Client) { + for _, e := range endpoints { + client.endpoints = append(client.endpoints, strings.TrimRight(e, "/")) + } } } @@ -110,33 +118,65 @@ func WithCredentials(username, password string) ClientOption { } var ( - ErrMissingAPIEnv = errors.New("missing environment variable PVE_API") - ErrMissingUserEnv = errors.New("missing environment variable PVE_USER") - ErrMissingPasswordEnv = errors.New("missing environment variable PVE_PASSWORD") + ErrMissingEndpointsEnv = errors.New("missing environment variable PVE_ENDPOINTS") + ErrMissingUserEnv = errors.New("missing environment variable PVE_USER") + ErrMissingPasswordEnv = errors.New("missing environment variable PVE_PASSWORD") + + ErrMissingEndpoints = errors.New("missing Endpoints in config") + ErrMissingUser = errors.New("missing User in config") + ErrMissingPassword = errors.New("missing Password in config") ) +type Config struct { + Endpoints []string `json:"endpoints"` + User string `json:"user"` + Password string `json:"password"` + Insecure bool `json:"insecure"` +} + +func ClientOptionsFromConfig(cfg Config) (options []ClientOption, err error) { + if len(cfg.Endpoints) == 0 { + err = ErrMissingEndpoints + return + } + if cfg.User == "" { + err = ErrMissingUser + return + } + if cfg.Password == "" { + err = ErrMissingPassword + return + } + options = []ClientOption{ + WithEndpoints(cfg.Endpoints), + WithCredentials(cfg.User, cfg.Password), + WithInsecureClient(cfg.Insecure), + } + return +} + func ClientOptionsFromEnv() (options []ClientOption, err error) { - api := os.Getenv("PVE_API") - if api == "" { - err = ErrMissingAPIEnv - //return + endpoints := os.Getenv("PVE_ENDPOINTS") + if endpoints == "" { + err = ErrMissingEndpointsEnv + return } user := os.Getenv("PVE_USER") if user == "" { err = ErrMissingUserEnv - //return + return } pass := os.Getenv("PVE_PASSWORD") if pass == "" { err = ErrMissingPasswordEnv - //return + return } insecure, _ := strconv.ParseBool(os.Getenv("PVE_INSECURE")) options = []ClientOption{ - WithEndpoint(api), + WithEndpoints(strings.Split(endpoints, ",")), WithCredentials(user, pass), WithInsecureClient(insecure), } @@ -174,6 +214,12 @@ func NewClient(options ...ClientOption) *Client { return client } +func (c *Client) getEndpoint() string { + if len(c.endpoints) == 0 { + return "" + } + return c.endpoints[0] +} func (c *Client) Auth() (err error) { if !time.Now().After(c.session.Time) { @@ -184,7 +230,7 @@ func (c *Client) Auth() (err error) { if !time.Now().After(c.session.Time) { return } - u := c.endpoint + "/access/ticket" + u := c.getEndpoint() + "/access/ticket" body := httpbody{"username": c.username, "password": c.password} r, err := http.NewRequest("POST", u, body.Reader()) if err != nil { @@ -210,7 +256,7 @@ func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Re if err != nil { return nil, err } - url := c.endpoint + path + url := c.getEndpoint() + path req, err := http.NewRequest(method, url, body) if err != nil { return nil, err diff --git a/scheme.go b/scheme.go index 6ae3b89..1efec5f 100644 --- a/scheme.go +++ b/scheme.go @@ -9,7 +9,10 @@ import ( "strings" ) -const PVEScheme = "pve" +const ( + PVEScheme = "pve" + PVESchemeURL = PVEScheme + "://" +) var ( ErrInvalidPVEURL = errors.New("invalid pve url scheme") @@ -51,7 +54,7 @@ func ServerRefFromURL(s string) (ref *ServerRef, err error) { } func NewURL(pool, node, id string) string { - return fmt.Sprintf("%s://%s/%s/%s", PVEScheme, pool, node, id) + return fmt.Sprintf("%s%s/%s/%s", PVESchemeURL, pool, node, id) } func K8sURL(url string) (string, error) {