iclient/incus_server.go
Rama develop · réplica de lectura del repositorio original.
package iclient
import (
"context"
"net/http"
"net/url"
"slices"
"strings"
"github.com/lxc/incus/v7/shared/api"
)
// GetClusterMembers returns every member of the cluster, each one whole.
func (c *Connection) GetClusterMembers(ctx context.Context) ([]api.ClusterMember, error) {
members := []api.ClusterMember{}
query := url.Values{}
query.Set("recursion", "1")
_, err := c.getStruct(ctx, "", "/cluster/members", query, &members)
if err != nil {
return nil, err
}
return members, nil
}
// GetServer returns the server's own description and its ETag.
func (c *Connection) GetServer(ctx context.Context) (*api.Server, string, error) {
server := api.Server{}
// The root of the API is /1.0 itself.
etag, err := c.getStruct(ctx, "", "", nil, &server)
if err != nil {
return nil, "", err
}
return &server, etag, nil
}
// HasExtension reports whether the server carries an API extension. It asks
// every time: a memo would be the one piece of mutable state on the connection.
func (c *Connection) HasExtension(ctx context.Context, extension string) (bool, error) {
server, _, err := c.GetServer(ctx)
if err != nil {
return false, err
}
return slices.Contains(server.APIExtensions, extension), nil
}
// IsIncusOS reports whether the server runs IncusOS, by asking incusd's /os
// proxy, which only answers there.
func (c *Connection) IsIncusOS(ctx context.Context) (bool, error) {
_, _, err := c.doPath(ctx, http.MethodGet, "/os/1.0", nil, "")
if err == nil {
return true, nil
}
// incusd's own 400 on the proxy means not IncusOS (cmd/incusd/api_os.go),
// and a server without the proxy (404) predates IncusOS.
if api.StatusErrorCheck(err, http.StatusBadRequest, http.StatusNotFound) {
return false, nil
}
return false, err
}
// GetConnectionInfo describes how this connection reaches the server.
func (c *Connection) GetConnectionInfo(ctx context.Context) (*ConnectionInfo, error) {
info := &ConnectionInfo{
Certificate: c.serverCert,
Protocol: "incus",
URL: c.baseURL,
SocketPath: c.socketPath,
}
server, _, err := c.GetServer(ctx)
if err != nil {
return nil, err
}
info.Target = server.Environment.ServerName
info.CertificateFingerprint = server.Environment.CertificateFingerprint
if c.socketPath == "" {
info.Addresses = append(info.Addresses, c.baseURL)
}
for _, addr := range server.Environment.Addresses {
// A wildcard address names no host, so it reaches nothing.
if strings.HasPrefix(addr, ":") {
continue
}
info.Addresses = append(info.Addresses, "https://"+addr)
}
return info, nil
}
// RawQuery sends a request to a path the caller built in full: the path is
// used verbatim, with no /1.0 prefix and no project.
func (c *Connection) RawQuery(ctx context.Context, method string, path string, data any, queryETag string) (*api.Response, string, error) {
return c.doPath(ctx, method, path, data, queryETag)
}