UI : vocabulaire unifié, comptes + mots de passe, choix par élément, clé AES auto
This commit is contained in:
1 parent
ee8343c69f
commit
2ca2f87307
19 files changed
+377
-143
No files matched your search
@@ -85,7 +85,7 @@ func ApplyWithLog(ctx context.Context, c *pve.Client, plan Plan, notify func(Ste
|
||||
err := c.Post(ctx, "cluster/sdn/lock", nil, &token)
|
||||
res.log("sdn lock", err)
|
||||
if err != nil {
|
||||
res.Err = fmt.Errorf("SDN lock (pending changes on the client?): %w", err)
|
||||
res.Err = fmt.Errorf("SDN lock (pending changes on the target?): %w", err)
|
||||
return res
|
||||
}
|
||||
rollback := func(cause error) {
|
||||
|
||||
@@ -158,13 +158,13 @@ func MakePlan(cfg *config.Config, cl *config.Client, ref, actual []model.Object)
|
||||
o, exists := cur[r.ID]
|
||||
if !exists {
|
||||
if a.Singleton() {
|
||||
plan.Errors = append(plan.Errors, fmt.Sprintf("%s: not found on client", r.Key()))
|
||||
plan.Errors = append(plan.Errors, fmt.Sprintf("%s: not found on the target", r.Key()))
|
||||
continue
|
||||
}
|
||||
for _, f := range a.Required(model.Object{Kind: k, ID: r.ID, Fields: desired}) {
|
||||
if _, ok := desired[f]; !ok {
|
||||
plan.Errors = append(plan.Errors,
|
||||
fmt.Sprintf("%s: field %q required for creation, add it to the mapping of client %s", r.Key(), f, cl.Name))
|
||||
fmt.Sprintf("%s: field %q required for creation, add it to the mapping of target %s", r.Key(), f, cl.Name))
|
||||
}
|
||||
}
|
||||
plan.Changes = append(plan.Changes, Change{Kind: k, ID: r.ID, Op: OpCreate, Set: desired,
|
||||
|
||||
@@ -151,3 +151,37 @@ func (p Plan) Digest() string {
|
||||
sum := sha256.Sum256(b)
|
||||
return hex.EncodeToString(sum[:12])
|
||||
}
|
||||
|
||||
// Skip removes from a plan the changes of the kinds left out of a replication
|
||||
// ("not synchronized" in the dry-run), then keeps what the remaining changes
|
||||
// need as Filter does: a group to create for an account stays in the plan.
|
||||
// keys narrows the plan to some objects first (empty: every object).
|
||||
func Skip(p Plan, keys []string, skip []model.Kind) Plan {
|
||||
if len(skip) == 0 {
|
||||
return Filter(p, keys)
|
||||
}
|
||||
out := map[model.Kind]bool{}
|
||||
for _, k := range skip {
|
||||
out[k] = true
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
for _, c := range p.Changes {
|
||||
keys = append(keys, c.Key())
|
||||
}
|
||||
for _, e := range p.Errors {
|
||||
if k, ok := ErrorKey(e); ok {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
var kept []string
|
||||
for _, k := range keys {
|
||||
if kind, _, _ := strings.Cut(k, "/"); !out[model.Kind(kind)] {
|
||||
kept = append(kept, k)
|
||||
}
|
||||
}
|
||||
if len(kept) == 0 {
|
||||
return Plan{Client: p.Client, Warnings: p.Warnings}
|
||||
}
|
||||
return Filter(p, kept)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"pve-confsync/internal/model"
|
||||
)
|
||||
|
||||
// Items left out of a run ("do not replicate") leave the plan, except what the
|
||||
// remaining changes need: the group to create for a new account.
|
||||
func TestSkipKinds(t *testing.T) {
|
||||
p := Plan{Client: "c", Changes: []Change{
|
||||
{Kind: model.KindGroup, ID: "ops", Op: OpCreate, Set: map[string]any{"comment": "Ops"}},
|
||||
{Kind: model.KindGroup, ID: "dev", Op: OpUpdate, Set: map[string]any{"comment": "Dev"}},
|
||||
{Kind: model.KindUser, ID: "bob@pve", Op: OpCreate, Set: map[string]any{"groups": "ops"}},
|
||||
{Kind: model.KindPassword, ID: "bob@pve", Op: OpCreate, Set: map[string]any{"hash": "$5$x"}},
|
||||
{Kind: model.KindVNet, ID: "v1", Op: OpUpdate, Set: map[string]any{"alias": "a"}},
|
||||
}, Errors: []string{"sdn-zone/z1: field \"bridge\" required for creation, add it to the mapping of target c"}}
|
||||
keys := func(p Plan) []string {
|
||||
var out []string
|
||||
for _, c := range p.Changes {
|
||||
out = append(out, c.Key())
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
got := Skip(p, nil, []model.Kind{model.KindGroup, model.KindZone, model.KindVNet})
|
||||
if want := []string{"pve-group/ops", "pve-user/bob@pve", "pve-password/bob@pve"}; !reflect.DeepEqual(keys(got), want) {
|
||||
t.Fatalf("changes: %v, want %v", keys(got), want)
|
||||
}
|
||||
if len(got.Errors) != 0 {
|
||||
t.Fatalf("the error of a skipped kind must not block: %v", got.Errors)
|
||||
}
|
||||
if got := Skip(p, nil, model.Kinds); len(got.Changes) != 0 || len(got.Errors) != 0 {
|
||||
t.Fatalf("everything skipped: %+v", got)
|
||||
}
|
||||
if got := Skip(p, nil, nil); len(got.Changes) != len(p.Changes) || len(got.Errors) != 1 {
|
||||
t.Fatalf("nothing skipped: %+v", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user