99 lines
3.0 KiB
Go
99 lines
3.0 KiB
Go
package adapter
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
|
|
"pve-confsync/internal/model"
|
|
"pve-confsync/internal/pve"
|
|
)
|
|
|
|
// DatacenterID is the id of the single datacenter options object.
|
|
const DatacenterID = "datacenter"
|
|
|
|
// pveDefaultMACPrefix is injected by PVE on read when mac_prefix is unset
|
|
// (PROXMOX_OUI in pve-cluster DataCenterConfig.pm); it is not a real setting.
|
|
const pveDefaultMACPrefix = "BC:24:11"
|
|
|
|
// datacenter handles GET/PUT /cluster/options (datacenter.cfg).
|
|
// GET returns several options parsed into objects/lists, PUT expects property strings:
|
|
// the canonical form is the property string (lists joined with ';' like datacenter.cfg).
|
|
type datacenter struct{}
|
|
|
|
func (datacenter) Kind() model.Kind { return model.KindDatacenter }
|
|
func (datacenter) SDN() bool { return false }
|
|
func (datacenter) Singleton() bool { return true }
|
|
|
|
func (datacenter) List(ctx context.Context, c *pve.Client, _ ReadMode, _ []model.Object) ([]model.Object, []string, error) {
|
|
var raw map[string]any
|
|
if err := c.Get(ctx, "cluster/options", nil, &raw); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
// allowed-tags: read-only, computed for the calling user.
|
|
fields := normalizeAPI(raw, "allowed-tags")
|
|
for k, v := range fields {
|
|
// top level lists (registered-tags) are stored as "a;b;c" in datacenter.cfg
|
|
if l, ok := v.([]string); ok {
|
|
fields[k] = strings.Join(l, ";")
|
|
}
|
|
}
|
|
if fields["description"] == "" {
|
|
delete(fields, "description")
|
|
}
|
|
if s, _ := fields["mac_prefix"].(string); strings.EqualFold(s, pveDefaultMACPrefix) {
|
|
delete(fields, "mac_prefix")
|
|
}
|
|
return []model.Object{{Kind: model.KindDatacenter, ID: DatacenterID, Fields: fields}}, nil, nil
|
|
}
|
|
|
|
// Fields synchronized by default; any other option is ignored unless the
|
|
// configuration says "sync".
|
|
var dcDefaultSync = map[string]bool{
|
|
"tag-style": true,
|
|
"registered-tags": true,
|
|
"user-tag-access": true,
|
|
"next-id": true,
|
|
}
|
|
|
|
func (datacenter) DefaultPolicy(f string) Policy {
|
|
if dcDefaultSync[f] {
|
|
return Sync
|
|
}
|
|
return Ignore
|
|
}
|
|
|
|
// Identity of the cluster or possible secrets (http_proxy may hold credentials).
|
|
func (datacenter) Forbidden(f string) bool {
|
|
switch f {
|
|
case "webauthn", "u2f", "http_proxy":
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (datacenter) Canonicalize(map[string]any) {}
|
|
|
|
func (datacenter) Required(model.Object) []string { return nil }
|
|
func (datacenter) Immutable(string) bool { return false }
|
|
|
|
func (datacenter) Create(context.Context, *pve.Client, model.Object, string) error {
|
|
return errors.New("datacenter options cannot be created")
|
|
}
|
|
|
|
func (datacenter) Delete(context.Context, *pve.Client, model.Object, string) error {
|
|
return errors.New("datacenter options cannot be deleted")
|
|
}
|
|
|
|
func (datacenter) Update(ctx context.Context, c *pve.Client, _ model.Object, set map[string]any, unset []string, _ string) error {
|
|
flat := map[string]any{}
|
|
for k, v := range set {
|
|
if l, ok := v.([]string); ok {
|
|
flat[k] = strings.Join(l, ";")
|
|
} else {
|
|
flat[k] = v
|
|
}
|
|
}
|
|
return c.Put(ctx, "cluster/options", form(flat, unset, ""), nil)
|
|
}
|