mockbunny

package
v0.0.0-...-20f4f05 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 11, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package mockbunny provides types and utilities for a mock bunny.net server used in testing the bunny-api-proxy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FailureInjectionMiddleware

func FailureInjectionMiddleware(state *State) func(http.Handler) http.Handler

FailureInjectionMiddleware creates a middleware that applies configured failure injection rules. It handles: error injection, latency injection, rate limiting, and malformed responses. Admin endpoints are excluded from failure injection to allow control of the mock server.

func LoggingMiddleware

func LoggingMiddleware(logger *slog.Logger) func(http.Handler) http.Handler

LoggingMiddleware logs all HTTP requests and responses to mockbunny. Only active when logger is provided (non-nil).

func VaryAcceptEncodingMiddleware

func VaryAcceptEncodingMiddleware(next http.Handler) http.Handler

VaryAcceptEncodingMiddleware adds the Vary: Accept-Encoding header to GET responses. This header indicates that the response content may vary based on the Accept-Encoding header. It mimics the behavior of the real bunny.net API which includes this header on GET responses.

Types

type AddRecordRequest

type AddRecordRequest struct {
	Type     int    `json:"Type"` // 0 = A, 1 = AAAA, 2 = CNAME, 3 = TXT, 4 = MX, 5 = SPF, 6 = Flatten, 7 = PullZone, 8 = SRV, 9 = CAA, 10 = PTR, 11 = Script, 12 = NS
	Name     string `json:"Name"`
	Value    string `json:"Value"`
	TTL      int32  `json:"Ttl"`
	Priority int32  `json:"Priority"`
	Weight   int32  `json:"Weight"`
	Port     int32  `json:"Port"`
	Flags    int    `json:"Flags"`
	Tag      string `json:"Tag"`
	Disabled bool   `json:"Disabled"`
	Comment  string `json:"Comment"`
}

AddRecordRequest represents the request body for creating a new DNS record.

type CertificateIssueResponse

type CertificateIssueResponse struct {
	Status      int    `json:"Status"`      // 0 = pending, 1 = issued, 2 = failed
	Message     string `json:"Message"`     // Status message (e.g., "Certificate issued successfully")
	Certificate string `json:"Certificate"` // The certificate in PEM format (stub data)
	DateCreated string `json:"DateCreated"` // ISO 8601 timestamp when certificate was created
	DateExpires string `json:"DateExpires"` // ISO 8601 timestamp when certificate expires
	ThumbPrint  string `json:"ThumbPrint"`  // Certificate thumbprint/fingerprint
	CN          string `json:"CN"`          // Common Name from the certificate
}

CertificateIssueResponse represents the response from the certificate issue endpoint. Returns status of the certificate issuance request along with certificate details if the certificate was successfully issued.

type CreateRecordRequest

type CreateRecordRequest struct {
	Type  int    `json:"Type"` // 0 = A, 1 = AAAA, 2 = CNAME, 3 = TXT, 4 = MX, 5 = SPF, 6 = Flatten, 7 = PullZone, 8 = SRV, 9 = CAA, 10 = PTR, 11 = Script, 12 = NS
	Name  string `json:"Name"`
	Value string `json:"Value"`
	TTL   int32  `json:"Ttl"`
}

CreateRecordRequest is the request body for POST /admin/zones/{zoneId}/records

type CreateZoneRequest

type CreateZoneRequest struct {
	Domain string `json:"domain"`
}

CreateZoneRequest is the request body for POST /admin/zones

type ErrorResponse

type ErrorResponse struct {
	ErrorKey string `json:"ErrorKey"`
	Field    string `json:"Field"`
	Message  string `json:"Message"`
}

ErrorResponse represents an error response from the API.

type FailureInjection

type FailureInjection struct {
	// contains filtered or unexported fields
}

FailureInjection holds state for simulating failure modes.

type ListZonesResponse

type ListZonesResponse struct {
	Items        []ZoneShortTime `json:"Items"`
	CurrentPage  int             `json:"CurrentPage"`
	TotalItems   int             `json:"TotalItems"`
	HasMoreItems bool            `json:"HasMoreItems"`
}

ListZonesResponse is a paginated response for the List Zones endpoint.

type MockBunnyTime

type MockBunnyTime struct {
	time.Time
}

MockBunnyTime wraps time.Time to serialize in bunny.net's format (with sub-second precision and Z suffix, matching real API behavior).

func (MockBunnyTime) MarshalJSON

func (t MockBunnyTime) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for MockBunnyTime. It returns timestamps in "2006-01-02T15:04:05.0000000Z" format (with sub-second precision and Z suffix), matching bunny.net's actual API creation endpoint.

func (*MockBunnyTime) UnmarshalJSON

func (t *MockBunnyTime) UnmarshalJSON(b []byte) error

UnmarshalJSON implements json.Unmarshaler for MockBunnyTime. It handles both RFC3339 format (with timezone) and bunny.net's format without timezone (treated as UTC).

type MockBunnyTimeShort

type MockBunnyTimeShort struct {
	time.Time
}

MockBunnyTimeShort wraps time.Time to serialize in bunny.net's short format (without sub-second precision, no Z suffix, matching list/get endpoints).

func (MockBunnyTimeShort) MarshalJSON

func (t MockBunnyTimeShort) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for MockBunnyTimeShort. It returns timestamps in "2006-01-02T15:04:05" format (without sub-second precision or Z suffix), matching bunny.net's actual API behavior on GET/list endpoints.

func (*MockBunnyTimeShort) UnmarshalJSON

func (t *MockBunnyTimeShort) UnmarshalJSON(b []byte) error

UnmarshalJSON implements json.Unmarshaler for MockBunnyTimeShort. It handles both RFC3339 format (with timezone) and bunny.net's format without timezone.

type Record

type Record struct {
	ID                    int64         `json:"Id"`
	Type                  int           `json:"Type"` // 0 = A, 1 = AAAA, 2 = CNAME, 3 = TXT, 4 = MX, 5 = SPF, 6 = Flatten, 7 = PullZone, 8 = SRV, 9 = CAA, 10 = PTR, 11 = Script, 12 = NS
	TTL                   int32         `json:"Ttl"`
	Value                 string        `json:"Value"`
	Name                  string        `json:"Name"`
	Weight                int32         `json:"Weight"`
	Priority              int32         `json:"Priority"`
	Port                  int32         `json:"Port"`
	Flags                 int           `json:"Flags"`
	Tag                   string        `json:"Tag"`
	Accelerated           bool          `json:"Accelerated"`
	AcceleratedPullZoneID int64         `json:"AcceleratedPullZoneId"`
	LinkName              string        `json:"LinkName"`
	IPGeoLocationInfo     interface{}   `json:"IPGeoLocationInfo"`
	GeolocationInfo       interface{}   `json:"GeolocationInfo"`
	MonitorStatus         int           `json:"MonitorStatus"` // 0 = Unknown, 1 = Online, 2 = Offline
	MonitorType           int           `json:"MonitorType"`   // 0 = None, 1 = Ping, 2 = Http, 3 = Monitor
	GeolocationLatitude   float64       `json:"GeolocationLatitude"`
	GeolocationLongitude  float64       `json:"GeolocationLongitude"`
	EnviromentalVariables []interface{} `json:"EnviromentalVariables"`
	LatencyZone           *string       `json:"LatencyZone"`
	SmartRoutingType      int           `json:"SmartRoutingType"` // 0 = None, 1 = Latency, 2 = Geolocation
	Disabled              bool          `json:"Disabled"`
	Comment               string        `json:"Comment"`
	AutoSslIssuance       bool          `json:"AutoSslIssuance"`
	AccelerationStatus    int           `json:"AccelerationStatus"`
}

Record represents a DNS record within a zone.

type Server

type Server struct {
	*httptest.Server
	// contains filtered or unexported fields
}

Server represents a mock bunny.net server for testing. It wraps httptest.Server and maintains internal state for zones and records.

func New

func New() *Server

New creates a new mock bunny.net server for testing. It initializes the server with placeholder routes that return 501 Not Implemented. The state is initialized with empty zones and auto-incrementing IDs. If DEBUG environment variable is set to "true", HTTP request/response logging is enabled. If BUNNY_API_KEY is set, API key authentication is required for DNS API endpoints.

func (*Server) AddZone

func (s *Server) AddZone(domain string) int64

AddZone adds a zone with sensible defaults and returns its ID. This method is thread-safe and commonly used for test setup.

func (*Server) AddZoneWithRecords

func (s *Server) AddZoneWithRecords(domain string, records []Record) int64

AddZoneWithRecords adds a zone with the given pre-populated records. Returns the zone ID. This method is thread-safe.

func (*Server) GetState

func (s *Server) GetState() map[int64]Zone

GetState returns a snapshot of all zones for debugging. The returned map contains copies of zones, safe to inspect without affecting state. This method is thread-safe.

func (*Server) GetZone

func (s *Server) GetZone(id int64) *Zone

GetZone returns a copy of a zone by ID, or nil if not found. The returned copy is safe to modify without affecting internal state. This method is thread-safe.

func (*Server) Handler

func (s *Server) Handler() chi.Router

Handler returns the HTTP handler for use with a standalone server. This allows running mockbunny outside of httptest.

func (*Server) SetLatency

func (s *Server) SetLatency(duration time.Duration, count int)

SetLatency schedules the next N requests to have the given delay. This method is thread-safe.

func (*Server) SetMalformedResponse

func (s *Server) SetMalformedResponse(count int)

SetMalformedResponse schedules the next N responses to return invalid JSON. This method is thread-safe.

func (*Server) SetNextError

func (s *Server) SetNextError(statusCode int, message string, count int)

SetNextError schedules the next N requests to fail with the given status code and message. This method is thread-safe.

func (*Server) SetRateLimit

func (s *Server) SetRateLimit(afterRequests int)

SetRateLimit schedules rate limiting: after the given number of successful requests, all subsequent requests will return 429 Too Many Requests. Setting afterRequests to 0 means immediate rate limiting. This method is thread-safe.

func (*Server) URL

func (s *Server) URL() string

URL returns the base URL of the mock server.

type State

type State struct {
	// contains filtered or unexported fields
}

State holds the internal mock server state.

func NewState

func NewState() *State

NewState creates a new State instance for the mock server.

type StateResponse

type StateResponse struct {
	Zones        []Zone `json:"zones"`
	NextZoneID   int64  `json:"nextZoneId"`
	NextRecordID int64  `json:"nextRecordId"`
}

StateResponse is the response for GET /admin/state

type Zone

type Zone struct {
	ID                       int64         `json:"Id"`
	Domain                   string        `json:"Domain"`
	Records                  []Record      `json:"Records"`
	DateModified             MockBunnyTime `json:"DateModified"`
	DateCreated              MockBunnyTime `json:"DateCreated"`
	NameserversDetected      bool          `json:"NameserversDetected"`
	CustomNameserversEnabled bool          `json:"CustomNameserversEnabled"`
	Nameserver1              string        `json:"Nameserver1"`
	Nameserver2              string        `json:"Nameserver2"`
	SoaEmail                 string        `json:"SoaEmail"`
	NameserversNextCheck     MockBunnyTime `json:"NameserversNextCheck,omitempty"`
	LoggingEnabled           bool          `json:"LoggingEnabled"`
	LoggingIPAnonymization   bool          `json:"LoggingIPAnonymizationEnabled"`
	LogAnonymizationType     int           `json:"LogAnonymizationType"` // 0 = OneDigit, 1 = Drop
	DnsSecEnabled            bool          `json:"DnsSecEnabled"`
	CertificateKeyType       int           `json:"CertificateKeyType"` // 0 = Ecdsa, 1 = Rsa
}

Zone represents a DNS zone.

func (*Zone) ZoneShortTime

func (z *Zone) ZoneShortTime() *ZoneShortTime

ZoneShortTime returns a copy of the zone with timestamps formatted using MockBunnyTimeShort (no sub-second precision, no Z suffix). Used for GET/list endpoint responses to match the real bunny.net API behavior.

type ZoneShortTime

type ZoneShortTime struct {
	ID                       int64              `json:"Id"`
	Domain                   string             `json:"Domain"`
	Records                  []Record           `json:"Records"`
	DateModified             MockBunnyTimeShort `json:"DateModified"`
	DateCreated              MockBunnyTimeShort `json:"DateCreated"`
	NameserversDetected      bool               `json:"NameserversDetected"`
	CustomNameserversEnabled bool               `json:"CustomNameserversEnabled"`
	Nameserver1              string             `json:"Nameserver1"`
	Nameserver2              string             `json:"Nameserver2"`
	SoaEmail                 string             `json:"SoaEmail"`
	NameserversNextCheck     MockBunnyTimeShort `json:"NameserversNextCheck,omitempty"`
	LoggingEnabled           bool               `json:"LoggingEnabled"`
	LoggingIPAnonymization   bool               `json:"LoggingIPAnonymizationEnabled"`
	LogAnonymizationType     int                `json:"LogAnonymizationType"` // 0 = OneDigit, 1 = Drop
	DnsSecEnabled            bool               `json:"DnsSecEnabled"`
	CertificateKeyType       int                `json:"CertificateKeyType"` // 0 = Ecdsa, 1 = Rsa
}

ZoneShortTime is a variant of Zone that uses MockBunnyTimeShort for timestamps. Used for GET/list endpoint responses to match the real bunny.net API behavior.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL