diff --git a/cmd/provider/provider.go b/cmd/provider/provider.go index 99134ad..06b370b 100644 --- a/cmd/provider/provider.go +++ b/cmd/provider/provider.go @@ -122,7 +122,7 @@ func main() { ra := c.String("routeros-address") rp := c.String("routeros-password") ru := c.String("routeros-username") - pc, err := provider.NewClient(provider.ClientOpts{ + pc, err := provider.NewClient(&provider.ClientOpts{ Address: ra, Logger: l.With("name", "client"), Password: rp, @@ -154,7 +154,7 @@ func main() { } else if fre != nil || fri != nil { df = endpoint.NewRegexDomainFilter(fri, fre) } - p, err := provider.NewProvider(provider.ProviderOpts{ + p, err := provider.NewProvider(&provider.ProviderOpts{ Client: pc, DomainFilter: df, Logger: l.With("name", "provider"), diff --git a/dev/create.sh b/dev/create.sh index 0445610..e9b94eb 100755 --- a/dev/create.sh +++ b/dev/create.sh @@ -1,5 +1,5 @@ #!/bin/sh -set -e +set -ex for command in minikube kubectl; do if ! command -v "${command}" > /dev/null; then @@ -23,11 +23,13 @@ echo "remove routeros container if exists" (docker stop routeros && docker rm routeros) || true echo "start routeros container" -cpu="host" -if [ ! -f "/dev/kvm" ]; then - cpu="qemu64" +kvm_arg="" +cpu="qemu64" +if [ -e "/dev/kvm" ]; then + kvm_arg="--device=/dev/kvm" + cpu="host" fi -docker run --name=routeros --rm --detach --publish=80:80 --publish=8728:8728 --cap-add=NET_ADMIN --device=/dev/net/tun --platform=linux/amd64 evilfreelancer/docker-routeros -cpu "${cpu}" +docker run --name=routeros --rm --detach --publish=80:80 --publish=8728:8728 --cap-add=NET_ADMIN --device=/dev/net/tun "${kvm_arg}" --platform=linux/amd64 evilfreelancer/docker-routeros -cpu "${cpu}" echo "apply external-dns crds" kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/external-dns/master/docs/contributing/crd-source/crd-manifest.yaml diff --git a/dev/dev.go.template b/dev/dev.go.template index c27f0f4..cb5ba79 100644 --- a/dev/dev.go.template +++ b/dev/dev.go.template @@ -99,7 +99,7 @@ func runWebhook() error { l := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ Level: slog.LevelDebug, })) - c, err := provider.NewClient(provider.ClientOpts{ + c, err := provider.NewClient(&provider.ClientOpts{ Address: "127.0.0.1:8728", Logger: l.With("name", "client"), Password: "", @@ -108,7 +108,7 @@ func runWebhook() error { if err != nil { return err } - p, err := provider.NewProvider(provider.ProviderOpts{ + p, err := provider.NewProvider(&provider.ProviderOpts{ Client: c, DomainFilter: endpoint.DomainFilter{}, Logger: l.With("name", "provider"), diff --git a/internal/provider/client.go b/internal/provider/client.go index 5e867a7..90dba48 100644 --- a/internal/provider/client.go +++ b/internal/provider/client.go @@ -40,20 +40,20 @@ type ClientOpts struct { // Creates a new [client] struct using the provided [ClientOpts] arguments. // Validates that the provided options are valid. -func NewClient(o ClientOpts) (client, error) { +func NewClient(o *ClientOpts) (*client, error) { l := o.Logger if l == nil { l = slog.New(slog.NewTextHandler(io.Discard, nil)) } cs := strings.Split(o.Address, ":") if len(cs) != 2 { - return client{}, fmt.Errorf("address not : format") + return &client{}, fmt.Errorf("address not : format") } _, err := strconv.ParseUint(cs[1], 0, 0) if err != nil { - return client{}, fmt.Errorf("port invalid: %w", err) + return &client{}, fmt.Errorf("port invalid: %w", err) } - return client{ + return &client{ address: o.Address, logger: l, password: o.Password, @@ -89,7 +89,7 @@ func (c *client) withClient(cb withClientCallback) error { // Performs a health check of the client by querying a simple routeros api // If the query fails and returns an error, this indicates the client is unhealthy -func (c client) Health() error { +func (c *client) Health() error { return c.withClient(func() error { _, err := c.client.RunArgs([]string{"/system/resource/print"}) return err @@ -143,7 +143,7 @@ func (e NotExternalDnsRecordError) Error() string { var recordMetadataPrefix = "external-dns:" // Retrieves metadata from a routeros dns record -func (c client) getRecordMetadata(v map[string]string) (recordMetadata, error) { +func (c *client) getRecordMetadata(v map[string]string) (recordMetadata, error) { co := v["comment"] rms, ok := strings.CutPrefix(co, recordMetadataPrefix) if !ok { @@ -210,12 +210,12 @@ func (c *client) listDnsRecords() ([]map[string]string, error) { // A key is used to connect [endpoint.Endpoint] and routeros ip dns records. // This function standardizes on this key. -func (c client) makeKey(rt string, n string) string { +func (c *client) makeKey(rt string, n string) string { return fmt.Sprintf("%s::%s", rt, n) } // Creates a new endpoint -func (c client) CreateEndpoint(e *endpoint.Endpoint) error { +func (c *client) CreateEndpoint(e *endpoint.Endpoint) error { rm := recordMetadata{} rmb, err := json.Marshal(rm) if err != nil { @@ -267,7 +267,7 @@ func (c client) CreateEndpoint(e *endpoint.Endpoint) error { } // Deletes an endpoint -func (c client) DeleteEndpoint(e *endpoint.Endpoint) error { +func (c *client) DeleteEndpoint(e *endpoint.Endpoint) error { rs, err := c.listDnsRecords() if err != nil { return err @@ -293,7 +293,7 @@ func (c client) DeleteEndpoint(e *endpoint.Endpoint) error { } // Lists all endpoints -func (c client) ListEndpoints() ([]*endpoint.Endpoint, error) { +func (c *client) ListEndpoints() ([]*endpoint.Endpoint, error) { rs, err := c.listDnsRecords() if err != nil { return []*endpoint.Endpoint{}, err diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 11cf36b..2943e49 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -32,12 +32,12 @@ type ProviderOpts struct { } // Creates a new [provider] using the provided options within [ProviderOpts] -func NewProvider(o ProviderOpts) (provider, error) { +func NewProvider(o *ProviderOpts) (*provider, error) { l := o.Logger if l == nil { l = slog.New(slog.NewTextHandler(io.Discard, nil)) } - return provider{ + return &provider{ client: o.Client, domainFilter: o.DomainFilter, logger: l, @@ -46,14 +46,14 @@ func NewProvider(o ProviderOpts) (provider, error) { // According to [ednsprovider.Provider], 'canonicalizes' endpoints to be consistent with that of the provider. // Currently, this provider does not need to canonicalize endpoints and simply returns the given input. -func (p provider) AdjustEndpoints(es []*endpoint.Endpoint) ([]*endpoint.Endpoint, error) { +func (p *provider) AdjustEndpoints(es []*endpoint.Endpoint) ([]*endpoint.Endpoint, error) { return es, nil } // Applies DNS changes to the target using this provider. // Returns an error if any update operation fails. // Attempts to apply all changes before returning an error on failure. -func (p provider) ApplyChanges(co context.Context, ch *plan.Changes) error { +func (p *provider) ApplyChanges(co context.Context, ch *plan.Changes) error { p.logger.Info("applying changes") errs := []error{} @@ -85,7 +85,7 @@ func (p provider) ApplyChanges(co context.Context, ch *plan.Changes) error { // Performs a health check of provider and client // Returns an error if the provider/client are unhealthy -func (p provider) Health() error { +func (p *provider) Health() error { p.logger.Info("performing health check") err := p.client.Health() if err != nil { @@ -95,12 +95,12 @@ func (p provider) Health() error { } // Gets the domain filters configured when the provider was launched -func (p provider) GetDomainFilter() endpoint.DomainFilter { +func (p *provider) GetDomainFilter() endpoint.DomainFilter { return p.domainFilter } // Gets known records attached to this provider -func (p provider) Records(c context.Context) ([]*endpoint.Endpoint, error) { +func (p *provider) Records(c context.Context) ([]*endpoint.Endpoint, error) { p.logger.Info("fetching records") return p.client.ListEndpoints() }