Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db7a9494d9 |
No files matched your search
@@ -489,8 +489,8 @@ provide:
|
|||||||
- `script/asupdate` — rebuild the AS list built into RouteWatch,
|
- `script/asupdate` — rebuild the AS list built into RouteWatch,
|
||||||
`pkg/asinfo/asdata.json.gz`, from the `as.csv` file of
|
`pkg/asinfo/asdata.json.gz`, from the `as.csv` file of
|
||||||
[ipverse/as-metadata](https://github.com/ipverse/as-metadata). It needs the
|
[ipverse/as-metadata](https://github.com/ipverse/as-metadata). It needs the
|
||||||
network. It runs `cmd/asinfo-gen`, which fails when it finds no AS. When
|
network. When the generator fails or finds no ASes, the old list stays and the
|
||||||
`cmd/asinfo-gen` fails, the old list stays and the script exits non-zero.
|
script exits non-zero.
|
||||||
|
|
||||||
Tests and the linter run only in Docker, as the `test` and `lint` phases of the
|
Tests and the linter run only in Docker, as the `test` and `lint` phases of the
|
||||||
`Dockerfile`; the image cannot be built unless both pass. Every `docker build`
|
`Dockerfile`; the image cannot be built unless both pass. Every `docker build`
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ const (
|
|||||||
columnsRead = 3
|
columnsRead = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var errUnexpectedHeader = errors.New("unexpected CSV header")
|
||||||
errUnexpectedHeader = errors.New("unexpected CSV header")
|
|
||||||
errNoASes = errors.New("no AS in the CSV")
|
|
||||||
)
|
|
||||||
|
|
||||||
// ASInfo represents information about an Autonomous System
|
// ASInfo represents information about an Autonomous System
|
||||||
type ASInfo struct {
|
type ASInfo struct {
|
||||||
@@ -85,7 +82,7 @@ func main() {
|
|||||||
// parseCSV reads as.csv from r and returns its ASes, with the handle and the
|
// parseCSV reads as.csv from r and returns its ASes, with the handle and the
|
||||||
// description as the file spells them. A header whose first columns are not
|
// description as the file spells them. A header whose first columns are not
|
||||||
// the AS number, the handle and the description is an error. A record that
|
// the AS number, the handle and the description is an error. A record that
|
||||||
// does not parse is logged and skipped. A file left with no AS is an error.
|
// does not parse is logged and skipped.
|
||||||
func parseCSV(r io.Reader) ([]ASInfo, error) {
|
func parseCSV(r io.Reader) ([]ASInfo, error) {
|
||||||
reader := csv.NewReader(r)
|
reader := csv.NewReader(r)
|
||||||
|
|
||||||
@@ -129,9 +126,5 @@ func parseCSV(r io.Reader) ([]ASInfo, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(asInfos) == 0 {
|
|
||||||
return nil, errNoASes
|
|
||||||
}
|
|
||||||
|
|
||||||
return asInfos, nil
|
return asInfos, nil
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -54,20 +53,3 @@ func TestParseCSVRejectsAnotherHeader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestParseCSVRejectsAFileWithNoASes parses files that hold no AS, one with
|
|
||||||
// only the header and one whose only record has no valid AS number. It
|
|
||||||
// expects errNoASes, so that make asupdate keeps the old list.
|
|
||||||
func TestParseCSVRejectsAFileWithNoASes(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
for _, asCSV := range []string{
|
|
||||||
"asn,handle,description,country-code\n",
|
|
||||||
"asn,handle,description,country-code\nAS1,LVLT-1,Level 3,US\n",
|
|
||||||
} {
|
|
||||||
_, err := parseCSV(strings.NewReader(asCSV))
|
|
||||||
if !errors.Is(err, errNoASes) {
|
|
||||||
t.Errorf("parseCSV(%q) = %v, want %v", asCSV, err, errNoASes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+11
-2
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# script/asupdate: rebuild the AS list built into RouteWatch from
|
# script/asupdate: rebuild the AS list built into RouteWatch from
|
||||||
# as.csv with cmd/asinfo-gen, which fails when it finds no AS. The new
|
# as.csv with cmd/asinfo-gen. The new list replaces the old one only
|
||||||
# list replaces the old one only when the generator succeeds. Otherwise
|
# when the generator succeeds and writes at least one AS. Otherwise
|
||||||
# the old list stays as it was and the script exits non-zero.
|
# the old list stays as it was and the script exits non-zero.
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
@@ -25,6 +25,15 @@ main() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# The generator writes a list of ASes with "[" alone on the first
|
||||||
|
# line. An empty list is "[]", and no list at all is "null".
|
||||||
|
first_line=""
|
||||||
|
read -r first_line <"$json" || true
|
||||||
|
if [ "$first_line" != "[" ]; then
|
||||||
|
echo "asupdate: the generator wrote no ASes; $AS_DATA is unchanged" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# -n leaves the time out of the file, so an unchanged list gives the
|
# -n leaves the time out of the file, so an unchanged list gives the
|
||||||
# same bytes.
|
# same bytes.
|
||||||
gzip -n -c <"$json" >"$AS_DATA_TMP"
|
gzip -n -c <"$json" >"$AS_DATA_TMP"
|
||||||
|
|||||||
Reference in new issue
Block a user