refactor: simplify Node SSR parsing and validation
This commit is contained in:
@@ -99,36 +99,48 @@ func parseNodeSsrBlock(content []byte) (nodeSsrBlock, error) {
|
|||||||
servers := make([]nodeSsrServer, 0, 2)
|
servers := make([]nodeSsrServer, 0, 2)
|
||||||
seen := make(map[int]struct{}, 2)
|
seen := make(map[int]struct{}, 2)
|
||||||
for index := begin + 1; index < end; index++ {
|
for index := begin + 1; index < end; index++ {
|
||||||
trimmed := strings.TrimSpace(lines[index])
|
server, found, err := parseNodeSsrServer(lines[index], index)
|
||||||
commented := strings.HasPrefix(trimmed, "# server ")
|
if err != nil {
|
||||||
active := strings.HasPrefix(trimmed, "server ")
|
return nodeSsrBlock{}, err
|
||||||
if !commented && !active {
|
|
||||||
if trimmed != "" {
|
|
||||||
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains an unexpected line: %q", trimmed)
|
|
||||||
}
|
}
|
||||||
|
if !found {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
serverText := strings.TrimPrefix(trimmed, "# ")
|
if _, exists := seen[server.port]; exists {
|
||||||
fields := strings.Fields(serverText)
|
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains duplicate port %d", server.port)
|
||||||
if len(fields) != 4 || fields[0] != "server" || fields[2] != "max_fails=1" || fields[3] != "fail_timeout=2s;" {
|
|
||||||
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream server line has an unsupported format: %q", trimmed)
|
|
||||||
}
|
}
|
||||||
_, portText, err := net.SplitHostPort(fields[1])
|
seen[server.port] = struct{}{}
|
||||||
if err != nil {
|
servers = append(servers, server)
|
||||||
return nodeSsrBlock{}, fmt.Errorf("parse managed Node SSR upstream address %q: %w", fields[1], err)
|
|
||||||
}
|
|
||||||
port, err := strconv.Atoi(portText)
|
|
||||||
if err != nil || (port != nodeSsrPort18910 && port != nodeSsrPort28910) {
|
|
||||||
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains unsupported port %q", portText)
|
|
||||||
}
|
|
||||||
if _, exists := seen[port]; exists {
|
|
||||||
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream contains duplicate port %d", port)
|
|
||||||
}
|
|
||||||
seen[port] = struct{}{}
|
|
||||||
servers = append(servers, nodeSsrServer{line: index, port: port, commented: commented})
|
|
||||||
}
|
}
|
||||||
if len(servers) != 2 {
|
if len(servers) != 2 {
|
||||||
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream must contain exactly two servers, got %d", len(servers))
|
return nodeSsrBlock{}, fmt.Errorf("managed Node SSR upstream must contain exactly two servers, got %d", len(servers))
|
||||||
}
|
}
|
||||||
return nodeSsrBlock{lines: lines, servers: servers}, nil
|
return nodeSsrBlock{lines: lines, servers: servers}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseNodeSsrServer parses one server line inside the managed Node SSR block.
|
||||||
|
func parseNodeSsrServer(line string, lineIndex int) (nodeSsrServer, bool, error) {
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
commented := strings.HasPrefix(trimmed, "# server ")
|
||||||
|
active := strings.HasPrefix(trimmed, "server ")
|
||||||
|
if !commented && !active {
|
||||||
|
if trimmed != "" {
|
||||||
|
return nodeSsrServer{}, false, fmt.Errorf("managed Node SSR upstream contains an unexpected line: %q", trimmed)
|
||||||
|
}
|
||||||
|
return nodeSsrServer{}, false, nil
|
||||||
|
}
|
||||||
|
serverText := strings.TrimPrefix(trimmed, "# ")
|
||||||
|
fields := strings.Fields(serverText)
|
||||||
|
if len(fields) != 4 || fields[0] != "server" || fields[2] != "max_fails=1" || fields[3] != "fail_timeout=2s;" {
|
||||||
|
return nodeSsrServer{}, false, fmt.Errorf("managed Node SSR upstream server line has an unsupported format: %q", trimmed)
|
||||||
|
}
|
||||||
|
_, portText, err := net.SplitHostPort(fields[1])
|
||||||
|
if err != nil {
|
||||||
|
return nodeSsrServer{}, false, fmt.Errorf("parse managed Node SSR upstream address %q: %w", fields[1], err)
|
||||||
|
}
|
||||||
|
port, err := strconv.Atoi(portText)
|
||||||
|
if err != nil || (port != nodeSsrPort18910 && port != nodeSsrPort28910) {
|
||||||
|
return nodeSsrServer{}, false, fmt.Errorf("managed Node SSR upstream contains unsupported port %q", portText)
|
||||||
|
}
|
||||||
|
return nodeSsrServer{line: lineIndex, port: port, commented: commented}, true, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,9 +88,17 @@ func validateNodeSsrContainerDeployment(deployment NodeSsrContainerDeployment) e
|
|||||||
if deployment.ActivePort != 18910 && deployment.ActivePort != 28910 {
|
if deployment.ActivePort != 18910 && deployment.ActivePort != 28910 {
|
||||||
return fmt.Errorf("Node SSR container deployment port must be 18910 or 28910: %d", deployment.ActivePort)
|
return fmt.Errorf("Node SSR container deployment port must be 18910 or 28910: %d", deployment.ActivePort)
|
||||||
}
|
}
|
||||||
for name, value := range map[string]string{"container name": deployment.ContainerName, "image digest": deployment.ImageDigest, "container ID": deployment.ContainerID} {
|
fields := []struct {
|
||||||
if value == "" || strings.TrimSpace(value) != value {
|
name string
|
||||||
return fmt.Errorf("exact Node SSR container %s is required", name)
|
value string
|
||||||
|
}{
|
||||||
|
{name: "container name", value: deployment.ContainerName},
|
||||||
|
{name: "image digest", value: deployment.ImageDigest},
|
||||||
|
{name: "container ID", value: deployment.ContainerID},
|
||||||
|
}
|
||||||
|
for _, field := range fields {
|
||||||
|
if field.value == "" || strings.TrimSpace(field.value) != field.value {
|
||||||
|
return fmt.Errorf("exact Node SSR container %s is required", field.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user