This commit is contained in:
vasyansk committed 2026-11-02 18:01:26 +07:00
1 parent 8417a144d6
commit b924923358
1 file changed
+54 -30
+54 -30
View File
@@ -337,40 +337,64 @@ func (c *Client) ApplyChanges(ctx context.Context, creds provider.Credentials, z
} }
base := "/zones/" + url.PathEscape(zoneID) + "/rrset" base := "/zones/" + url.PathEscape(zoneID) + "/rrset"
applied := 0
for _, d := range cs.Diffs { for _, d := range cs.Diffs {
if d.ReadOnly || d.Kind == diff.InSync { if d.ReadOnly || d.Kind == diff.InSync {
continue continue
} }
switch d.Kind { if err := c.applyOne(ctx, base, tok, idByKey, d); err != nil {
case diff.Add: // Apply is not atomic: name the failing record and how many
if d.Desired == nil { // diffs already went through, so the operator can see the state.
return fmt.Errorf("selectel: add/update diff without Desired record") return fmt.Errorf("%s (применено до ошибки: %d): %w", describeDiff(d), applied, err)
} }
if err := c.do(ctx, http.MethodPost, base, tok, toRRSet(*d.Desired), nil); err != nil { applied++
return err }
} return nil
case diff.Update: }
if d.Desired == nil {
return fmt.Errorf("selectel: add/update diff without Desired record") // describeDiff renders a diff for error messages: "add CNAME mail.x. [value]".
} func describeDiff(d diff.RecordDiff) string {
id, ok := idByKey[d.Desired.Key()] rec := d.Desired
if !ok { if rec == nil {
return fmt.Errorf("cannot update: rrset %s not found in zone", d.Desired.Key()) rec = d.Actual
} }
if err := c.do(ctx, http.MethodPatch, base+"/"+url.PathEscape(id), tok, toRRSet(*d.Desired), nil); err != nil { out := fmt.Sprintf("%s %s", d.Kind, d.Key())
return err if rec != nil {
} out += fmt.Sprintf(" ttl=%d %q", rec.TTL, rec.Values)
case diff.Delete: }
if d.Actual == nil { return out
return fmt.Errorf("selectel: delete diff without Actual record") }
}
id, ok := idByKey[d.Actual.Key()] func (c *Client) applyOne(ctx context.Context, base, tok string, idByKey map[string]string, d diff.RecordDiff) error {
if !ok { switch d.Kind {
return fmt.Errorf("cannot delete: rrset %s not found in zone", d.Actual.Key()) case diff.Add:
} if d.Desired == nil {
if err := c.do(ctx, http.MethodDelete, base+"/"+url.PathEscape(id), tok, nil, nil); err != nil { return fmt.Errorf("selectel: add/update diff without Desired record")
return err }
} if err := c.do(ctx, http.MethodPost, base, tok, toRRSet(*d.Desired), nil); err != nil {
return err
}
case diff.Update:
if d.Desired == nil {
return fmt.Errorf("selectel: add/update diff without Desired record")
}
id, ok := idByKey[d.Desired.Key()]
if !ok {
return fmt.Errorf("cannot update: rrset %s not found in zone", d.Desired.Key())
}
if err := c.do(ctx, http.MethodPatch, base+"/"+url.PathEscape(id), tok, toRRSet(*d.Desired), nil); err != nil {
return err
}
case diff.Delete:
if d.Actual == nil {
return fmt.Errorf("selectel: delete diff without Actual record")
}
id, ok := idByKey[d.Actual.Key()]
if !ok {
return fmt.Errorf("cannot delete: rrset %s not found in zone", d.Actual.Key())
}
if err := c.do(ctx, http.MethodDelete, base+"/"+url.PathEscape(id), tok, nil, nil); err != nil {
return err
} }
} }
return nil return nil