diff --git a/.golangci.yml b/.golangci.yml index dd3d234..667666a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,6 +2,7 @@ run: timeout: 5m linters: + disable-all: true enable: - gofmt - govet diff --git a/internal/asnresolve/ripestat.go b/internal/asnresolve/ripestat.go index 5107d44..4baec1f 100644 --- a/internal/asnresolve/ripestat.go +++ b/internal/asnresolve/ripestat.go @@ -42,7 +42,7 @@ func AnnouncedPrefixes(ctx context.Context, hc *http.Client, asn int64) ([]netip if err != nil { return nil, fmt.Errorf("ripestat fetch AS%d: %w", asn, err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() body, err := io.ReadAll(io.LimitReader(resp.Body, 32<<20)) if err != nil { return nil, err @@ -52,8 +52,8 @@ func AnnouncedPrefixes(ctx context.Context, hc *http.Client, asn int64) ([]netip } var wrap struct { - Status string `json:"status"` - Data struct { + Status string `json:"status"` + Data struct { Prefixes []struct { Prefix string `json:"prefix"` } `json:"prefixes"` @@ -104,7 +104,7 @@ func ASHolderName(ctx context.Context, hc *http.Client, asn int64) (string, erro if err != nil { return "", fmt.Errorf("ripestat as-overview AS%d: %w", asn, err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() body, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20)) if err != nil { return "", err diff --git a/internal/birdfmt/bgp.go b/internal/birdfmt/bgp.go index 5690a9c..984f71c 100644 --- a/internal/birdfmt/bgp.go +++ b/internal/birdfmt/bgp.go @@ -60,10 +60,10 @@ func RenderBGPTemplates(opts BGPTemplatesOptions) (string, error) { // BGPPeerFromTemplateOptions describes protocol bgp NAME from TEMPLATE { … }. type BGPPeerFromTemplateOptions struct { - ProtocolName string - TemplateName string - NeighborIP string - NeighborASN uint32 + ProtocolName string + TemplateName string + NeighborIP string + NeighborASN uint32 // If set, emits "local … as …" before neighbor (overrides template local/ASN for this peer). OverrideLocalIP string OverrideLocalASN uint32 diff --git a/internal/bundle/pack.go b/internal/bundle/pack.go index b8d2778..135b522 100644 --- a/internal/bundle/pack.go +++ b/internal/bundle/pack.go @@ -17,12 +17,12 @@ import ( // Manifest describes bundle contents for evobgp-node verification. type Manifest struct { - RevisionID string `json:"revision_id"` - SpeakerID string `json:"speaker_id,omitempty"` - CreatedAt time.Time `json:"created_at"` - Files []FileEntry `json:"files"` - Algorithm string `json:"signature_algorithm"` - PublicKeyB64 string `json:"public_key_base64"` + RevisionID string `json:"revision_id"` + SpeakerID string `json:"speaker_id,omitempty"` + CreatedAt time.Time `json:"created_at"` + Files []FileEntry `json:"files"` + Algorithm string `json:"signature_algorithm"` + PublicKeyB64 string `json:"public_key_base64"` } // FileEntry is one file inside the bundle archive. diff --git a/internal/bundle/verify.go b/internal/bundle/verify.go index af5692c..70344ca 100644 --- a/internal/bundle/verify.go +++ b/internal/bundle/verify.go @@ -27,7 +27,7 @@ func VerifyGzippedTar(bundle []byte, pub ed25519.PublicKey) (*VerifiedContents, if err != nil { return nil, err } - defer gr.Close() + defer func() { _ = gr.Close() }() var manifestRaw []byte var sig []byte diff --git a/internal/httpapi/problem.go b/internal/httpapi/problem.go index 12a39e1..a3ff73c 100644 --- a/internal/httpapi/problem.go +++ b/internal/httpapi/problem.go @@ -7,21 +7,21 @@ import ( ) const ( - internalErrorDetail = "an internal error occurred" - badGatewayDetail = "upstream request failed" - notFoundDetail = "resource not found" - invalidInputDetail = "invalid request data" - cdnExtractDetail = "could not extract prefixes from source" - csvInvalidRowDetail = "invalid row in csv file" + internalErrorDetail = "an internal error occurred" + badGatewayDetail = "upstream request failed" + notFoundDetail = "resource not found" + invalidInputDetail = "invalid request data" + cdnExtractDetail = "could not extract prefixes from source" + csvInvalidRowDetail = "invalid row in csv file" ) // Problem is RFC 9457 application/problem+json. type Problem struct { - Type string `json:"type,omitempty"` - Title string `json:"title"` - Status int `json:"status"` - Detail string `json:"detail,omitempty"` - Instance string `json:"instance,omitempty"` + Type string `json:"type,omitempty"` + Title string `json:"title"` + Status int `json:"status"` + Detail string `json:"detail,omitempty"` + Instance string `json:"instance,omitempty"` } func writeProblem(w http.ResponseWriter, status int, title, detail string) { diff --git a/internal/httpapi/routes_crud.go b/internal/httpapi/routes_crud.go index bf911e3..50adeaf 100644 --- a/internal/httpapi/routes_crud.go +++ b/internal/httpapi/routes_crud.go @@ -258,7 +258,7 @@ func (s *Server) handlePreviewCDNSource(w http.ResponseWriter, r *http.Request) writeBadGateway(w, "cdn preview fetch", err) return } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { _, _ = io.Copy(io.Discard, resp.Body) writeBadGateway(w, "cdn preview fetch", fmt.Errorf("upstream status: %s", resp.Status)) diff --git a/internal/httpapi/routes_crud_csv_test.go b/internal/httpapi/routes_crud_csv_test.go index 2d5fb4f..9750d6f 100644 --- a/internal/httpapi/routes_crud_csv_test.go +++ b/internal/httpapi/routes_crud_csv_test.go @@ -34,7 +34,7 @@ func TestModuleEntriesCSVImportExportIPRanges(t *testing.T) { if err != nil { t.Fatal(err) } - defer respList.Body.Close() + defer func() { _ = respList.Body.Close() }() if respList.StatusCode != http.StatusOK { b, _ := io.ReadAll(respList.Body) t.Fatalf("communities status %d: %s", respList.StatusCode, b) @@ -59,7 +59,7 @@ func TestModuleEntriesCSVImportExportIPRanges(t *testing.T) { if err != nil { t.Fatal(err) } - defer respImport.Body.Close() + defer func() { _ = respImport.Body.Close() }() if respImport.StatusCode != http.StatusOK { b, _ := io.ReadAll(respImport.Body) t.Fatalf("import status %d: %s", respImport.StatusCode, b) @@ -80,7 +80,7 @@ func TestModuleEntriesCSVImportExportIPRanges(t *testing.T) { if err != nil { t.Fatal(err) } - defer respExport.Body.Close() + defer func() { _ = respExport.Body.Close() }() if respExport.StatusCode != http.StatusOK { b, _ := io.ReadAll(respExport.Body) t.Fatalf("export status %d: %s", respExport.StatusCode, b) diff --git a/internal/httpapi/routes_crud_list_test.go b/internal/httpapi/routes_crud_list_test.go index e220bf2..53ae9a8 100644 --- a/internal/httpapi/routes_crud_list_test.go +++ b/internal/httpapi/routes_crud_list_test.go @@ -35,7 +35,7 @@ func TestNestedModuleListPagination(t *testing.T) { t.Fatal(err) } _, _ = io.Copy(io.Discard, resp.Body) - resp.Body.Close() + _ = resp.Body.Close() if resp.StatusCode != http.StatusCreated { t.Fatalf("create entry %d: status %d", i, resp.StatusCode) } @@ -47,7 +47,7 @@ func TestNestedModuleListPagination(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("list status %d: %s", resp.StatusCode, b) @@ -73,7 +73,7 @@ func TestNestedModuleListPagination(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp2.Body.Close() + defer func() { _ = resp2.Body.Close() }() var page2 struct { Items []map[string]any `json:"items"` HasMore bool `json:"has_more"` diff --git a/internal/httpapi/server.go b/internal/httpapi/server.go index 306c00e..76b7803 100644 --- a/internal/httpapi/server.go +++ b/internal/httpapi/server.go @@ -32,10 +32,10 @@ type Server struct { type Options struct { APIKeys string // DatabaseURL enables PostgreSQL-backed store (migrations applied on connect). - DatabaseURL string - InsecureDev bool - SeedDemo bool - BundleSeedHex string + DatabaseURL string + InsecureDev bool + SeedDemo bool + BundleSeedHex string CORSAllowedOrigins string } diff --git a/internal/httpapi/server_test.go b/internal/httpapi/server_test.go index 5bc05fc..7a9f993 100644 --- a/internal/httpapi/server_test.go +++ b/internal/httpapi/server_test.go @@ -51,7 +51,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -76,7 +76,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusAccepted { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -97,7 +97,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusAccepted { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -118,7 +118,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -132,7 +132,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -162,7 +162,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { t.Fatal(err) } b, _ := io.ReadAll(resp.Body) - resp.Body.Close() + _ = resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("%s status %d: %s", path, resp.StatusCode, b) } @@ -185,7 +185,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -215,7 +215,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -255,7 +255,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusForbidden { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d want 403: %s", resp.StatusCode, b) @@ -269,7 +269,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusAccepted { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -289,7 +289,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusAccepted { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -314,7 +314,7 @@ func TestAPIRefreshApplyJobsBundle(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) @@ -341,7 +341,7 @@ func waitJob(t *testing.T, client *http.Client, base, token, jobID string) { t.Fatal(err) } b, _ := io.ReadAll(resp.Body) - resp.Body.Close() + _ = resp.Body.Close() var body struct { Status string `json:"status"` } @@ -405,7 +405,7 @@ func TestVersionEndpoints(t *testing.T) { if err != nil { t.Fatal(err) } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("status %d: %s", resp.StatusCode, b) diff --git a/internal/nodecli/commands.go b/internal/nodecli/commands.go index 6a6b774..5d7079e 100644 --- a/internal/nodecli/commands.go +++ b/internal/nodecli/commands.go @@ -66,7 +66,7 @@ func fetchLatestRevision(base, token, speaker string) (string, error) { if err != nil { return "", err } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) return "", fmt.Errorf("latest revision: %s: %s", resp.Status, strings.TrimSpace(string(b))) @@ -94,7 +94,7 @@ func fetchBundle(base, token, speaker, revision string) ([]byte, error) { if err != nil { return nil, err } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("bundle: %s: %s", resp.Status, strings.TrimSpace(string(b))) diff --git a/internal/nodecli/nodecli.go b/internal/nodecli/nodecli.go index d000fe7..1129aec 100644 --- a/internal/nodecli/nodecli.go +++ b/internal/nodecli/nodecli.go @@ -27,7 +27,7 @@ func Run(args []string) int { // Usage prints CLI help to w. func Usage(w interface{ Write([]byte) (int, error) }) { - fmt.Fprintf(w, `Usage: + _, _ = fmt.Fprintf(w, `Usage: evobgp-node pull-bundle -base-url URL -token TOKEN -speaker-id ID [-revision-id ID] [-o path] evobgp-node verify-bundle -f bundle.tar.gz (-pubkey-base64 B64 | -pubkey-hex HEX) evobgp-node apply-bundle -f bundle.tar.gz -extract-dir DIR (-pubkey-base64 B64 | -pubkey-hex HEX) diff --git a/internal/pipeline/cdn_snapshot.go b/internal/pipeline/cdn_snapshot.go index 0f55792..f3441fc 100644 --- a/internal/pipeline/cdn_snapshot.go +++ b/internal/pipeline/cdn_snapshot.go @@ -126,7 +126,7 @@ func applyCDNSourceHTTPResult(ctx context.Context, st store.Backend, hc *http.Cl return nil, fmt.Errorf("cdn url %s: 304 without cached prefixes", u) } } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { _, _ = io.Copy(io.Discard, resp.Body) diff --git a/internal/pipeline/materialize_regression_test.go b/internal/pipeline/materialize_regression_test.go index 20fb2a2..f96fcd9 100644 --- a/internal/pipeline/materialize_regression_test.go +++ b/internal/pipeline/materialize_regression_test.go @@ -46,4 +46,3 @@ func TestBuildPreviewFragments_SamePrefixDifferentCommunity(t *testing.T) { t.Fatalf("expected deterministic static preview text, got first:\n%s\nsecond:\n%s", staticV4, staticV4Second) } } - diff --git a/internal/pipeline/refresh.go b/internal/pipeline/refresh.go index 365280b..336bdca 100644 --- a/internal/pipeline/refresh.go +++ b/internal/pipeline/refresh.go @@ -306,7 +306,7 @@ func resolveDomainWithDOHMessage(ctx context.Context, hc *http.Client, baseURL, if err != nil { return nil, err } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024)) return nil, fmt.Errorf("doh dns-message status %s: %s", resp.Status, strings.TrimSpace(string(body))) @@ -378,7 +378,7 @@ func resolveDomainWithDOHJSON(ctx context.Context, hc *http.Client, baseURL, hos if err != nil { return nil, err } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024)) return nil, fmt.Errorf("doh status %s: %s", resp.Status, strings.TrimSpace(string(body))) @@ -725,15 +725,15 @@ func dedupeSortedPrefixLines(rows []store.PrefixRow) []prefixHashLine { } func writePrefixLinesHash(h interface{ Write([]byte) (int, error) }, tenantID string, lines []prefixHashLine) { - h.Write([]byte(strings.TrimSpace(tenantID))) - h.Write([]byte{0}) + _, _ = h.Write([]byte(strings.TrimSpace(tenantID))) + _, _ = h.Write([]byte{0}) for _, l := range lines { - h.Write([]byte(l.p)) - h.Write([]byte{1}) - h.Write([]byte(l.c)) - h.Write([]byte{1}) - h.Write([]byte(l.s)) - h.Write([]byte{0}) + _, _ = h.Write([]byte(l.p)) + _, _ = h.Write([]byte{1}) + _, _ = h.Write([]byte(l.c)) + _, _ = h.Write([]byte{1}) + _, _ = h.Write([]byte(l.s)) + _, _ = h.Write([]byte{0}) } } diff --git a/internal/repository/postgres.go b/internal/repository/postgres.go index ca5b986..e4d58b1 100644 --- a/internal/repository/postgres.go +++ b/internal/repository/postgres.go @@ -28,7 +28,7 @@ func agentDebugNDJSON3214(hypothesisID, location, message string, data map[strin if err != nil { return } - defer f.Close() + defer func() { _ = f.Close() }() var ms runtime.MemStats runtime.ReadMemStats(&ms) payload := map[string]any{ diff --git a/internal/scheduler/run.go b/internal/scheduler/run.go index 7487f08..10deb9f 100644 --- a/internal/scheduler/run.go +++ b/internal/scheduler/run.go @@ -121,7 +121,7 @@ func postTenantRefresh(ctx context.Context, deps *Deps, moduleIDs []string, idem if err != nil { return err } - defer resp.Body.Close() + defer func() { _ = resp.Body.Close() }() if resp.StatusCode == http.StatusNoContent || resp.StatusCode == http.StatusAccepted { return nil } diff --git a/internal/store/memory.go b/internal/store/memory.go index 42eb005..4b5956b 100644 --- a/internal/store/memory.go +++ b/internal/store/memory.go @@ -33,13 +33,13 @@ type Memory struct { peers map[string]*BGPPeer - dohProfiles map[string]*DohProfile - communities map[string]*Community - cdnSources map[string]*CDNSource - asEntries map[string]*ASEntry - domainEnt map[string]*DomainEntry - ipRanges map[string]*IPRangeEntry - settings map[string]map[string]any // tenantID -> key -> JSON-compatible value + dohProfiles map[string]*DohProfile + communities map[string]*Community + cdnSources map[string]*CDNSource + asEntries map[string]*ASEntry + domainEnt map[string]*DomainEntry + ipRanges map[string]*IPRangeEntry + settings map[string]map[string]any // tenantID -> key -> JSON-compatible value revPrefixes map[string][]PrefixRow moduleSnapshots map[string]*moduleSnapshotRec asnPrefixCache map[int64]*ASNPrefixCacheEntry diff --git a/internal/store/peer_neighbor_test.go b/internal/store/peer_neighbor_test.go index 2082382..c4fde9c 100644 --- a/internal/store/peer_neighbor_test.go +++ b/internal/store/peer_neighbor_test.go @@ -19,9 +19,9 @@ func TestEffectivePeerEnabledOnCreate(t *testing.T) { func TestParsePeerNeighbor(t *testing.T) { tests := []struct { - in string - want string - wantOK bool + in string + want string + wantOK bool }{ {"192.168.0.2", "192.168.0.2", true}, {"192.168.0.2/32", "192.168.0.2", true},