package engine import ( "encoding/json" "jarl/internal/model" ) // Operation kinds. const ( OpZoneCreate = "zone.create" OpZoneUpdate = "zone.update" OpZoneDelete = "zone.delete" OpRecordCreate = "record.create" OpRecordUpdate = "record.update" OpRecordDelete = "record.delete" OpRRSetReplace = "rrset.replace" OpViewCreate = "view.create" OpViewUpdate = "view.update" OpViewDelete = "view.delete" OpViewReorder = "view.reorder" OpACLCreate = "acl.create" OpACLUpdate = "acl.update" OpACLDelete = "acl.delete" OpTSIGCreate = "tsig.create" OpTSIGUpdate = "tsig.update" OpTSIGDelete = "tsig.delete" OpOptionCreate = "option.create" OpOptionUpdate = "option.update" OpOptionDelete = "option.delete" OpSettingsUpdate = "settings.update" ) // OpKinds lists all operation kinds. var OpKinds = []string{OpZoneCreate, OpZoneUpdate, OpZoneDelete, OpRecordCreate, OpRecordUpdate, OpRecordDelete, OpRRSetReplace, OpViewCreate, OpViewUpdate, OpViewDelete, OpViewReorder, OpACLCreate, OpACLUpdate, OpACLDelete, OpTSIGCreate, OpTSIGUpdate, OpTSIGDelete, OpOptionCreate, OpOptionUpdate, OpOptionDelete, OpSettingsUpdate} // Request is an operation as submitted by a client. Requests are expanded // into one or more stored operations (for example an A record with "ptr" // also creates the matching PTR record). type Request struct { Op string `json:"op"` // ID is the object to update or delete. ID int64 `json:"id,omitempty"` // BaseVersion, if set, makes the request fail when the object's // version differs (optimistic locking). Otherwise the version at // staging time is recorded. BaseVersion int `json:"base_version,omitempty"` Data json.RawMessage `json:"data,omitempty"` } // NewRequest builds a request with data marshaled from an input struct. func NewRequest(op string, id int64, data any) Request { r := Request{Op: op, ID: id} if data != nil { b, err := json.Marshal(data) if err != nil { panic(err) } r.Data = b } return r } // SOAInput sets SOA fields of a primary zone. type SOAInput struct { MName *string `json:"mname,omitempty"` RName *string `json:"rname,omitempty"` // mailbox name or email address Serial *uint32 `json:"serial,omitempty"` Refresh *uint32 `json:"refresh,omitempty"` Retry *uint32 `json:"retry,omitempty"` Expire *uint32 `json:"expire,omitempty"` Minimum *uint32 `json:"minimum,omitempty"` } // ZoneInput creates or updates a zone. type ZoneInput struct { // Name is the zone name. For create, a CIDR prefix such as // "192.168.1.0/24" creates the matching reverse zone. Name *string `json:"name,omitempty"` ViewID *int64 `json:"view_id,omitempty"` View *string `json:"view,omitempty"` // view name, alternative to view_id Type *string `json:"type,omitempty"` InView *string `json:"in_view,omitempty"` File *string `json:"file,omitempty"` SOA *SOAInput `json:"soa,omitempty"` DefaultTTL *uint32 `json:"default_ttl,omitempty"` SerialPolicy *string `json:"serial_policy,omitempty"` Comment *string `json:"comment,omitempty"` // Create only: name servers for the apex NS records (default: the // configured default name servers), additional records, and a zone to // copy records from. Nameservers []string `json:"nameservers,omitempty"` Records []RecordInput `json:"records,omitempty"` CloneFrom int64 `json:"clone_from,omitempty"` // Options (create only) are zone options to set, e.g. primaries for a // secondary zone or forwarders for a forward zone. Options []ZoneOption `json:"options,omitempty"` } // ZoneOption is an option given when creating a zone. type ZoneOption struct { Name string `json:"name"` Value string `json:"value"` Comment string `json:"comment,omitempty"` } // RecordInput creates, updates or (by match) deletes a record. type RecordInput struct { ZoneID int64 `json:"zone_id,omitempty"` Zone string `json:"zone,omitempty"` // zone name, alternative to zone_id View string `json:"view,omitempty"` // view of Zone Name *string `json:"name,omitempty"` Type *string `json:"type,omitempty"` TTL model.Opt[uint32] `json:"ttl,omitzero"` // null: use the zone default Data *string `json:"data,omitempty"` Comment *string `json:"comment,omitempty"` // PTR also creates (or deletes) the matching PTR record in the // reverse zone, for A and AAAA records. PTR bool `json:"ptr,omitempty"` // MissingOK makes a delete-by-match succeed when nothing matches. MissingOK bool `json:"missing_ok,omitempty"` } // RRSetInput replaces all records of one name and type. type RRSetInput struct { ZoneID int64 `json:"zone_id,omitempty"` Zone string `json:"zone,omitempty"` View string `json:"view,omitempty"` Name string `json:"name"` Type string `json:"type"` TTL model.Opt[uint32] `json:"ttl,omitzero"` Data []string `json:"data"` Comment *string `json:"comment,omitempty"` // NewIDs are allocated for records that need to be created. NewIDs []int64 `json:"new_ids,omitempty"` } // ViewInput creates or updates a view. type ViewInput struct { Name *string `json:"name,omitempty"` MatchClients *[]string `json:"match_clients,omitempty"` MatchDestinations *[]string `json:"match_destinations,omitempty"` MatchRecursiveOnly model.Opt[bool] `json:"match_recursive_only,omitzero"` Comment *string `json:"comment,omitempty"` Position *int `json:"position,omitempty"` // AdoptZones (create) moves all zones that are not in a view into the // new view; named requires every zone to be in a view once views // are used. AdoptZones bool `json:"adopt_zones,omitempty"` // Cascade (delete) also deletes the view's zones. Cascade bool `json:"cascade,omitempty"` } // ReorderInput sets the order of views. type ReorderInput struct { IDs []int64 `json:"ids"` } // ACLInput creates or updates an ACL. type ACLInput struct { Name *string `json:"name,omitempty"` Elements *[]string `json:"elements,omitempty"` Comment *string `json:"comment,omitempty"` } // TSIGInput creates or updates a TSIG key. A missing secret on create is // generated. type TSIGInput struct { Name *string `json:"name,omitempty"` Algorithm *string `json:"algorithm,omitempty"` Secret *string `json:"secret,omitempty"` Comment *string `json:"comment,omitempty"` } // OptionInput creates or updates an option. type OptionInput struct { Scope *string `json:"scope,omitempty"` // options, view, zone, toplevel ScopeID *int64 `json:"scope_id,omitempty"` // view or zone ID Name *string `json:"name,omitempty"` Value *string `json:"value,omitempty"` Comment *string `json:"comment,omitempty"` Position *int `json:"position,omitempty"` } // SettingsInput updates Jarl's settings. type SettingsInput struct { DefaultTTL *uint32 `json:"default_ttl,omitempty"` Nameservers *[]string `json:"nameservers,omitempty"` RName *string `json:"rname,omitempty"` Refresh *uint32 `json:"refresh,omitempty"` Retry *uint32 `json:"retry,omitempty"` Expire *uint32 `json:"expire,omitempty"` NegativeTTL *uint32 `json:"negative_ttl,omitempty"` SerialPolicy *string `json:"serial_policy,omitempty"` } // DeleteInput carries options for delete operations. type DeleteInput struct { Cascade bool `json:"cascade,omitempty"` }