]> ruderich.org/simon Gitweb - safcm/safcm.git/blob - cmd/safcm/config/hosts.go
Use SPDX license identifiers
[safcm/safcm.git] / cmd / safcm / config / hosts.go
1 // Config: parse hosts.yaml
2
3 // SPDX-License-Identifier: GPL-3.0-or-later
4 // Copyright (C) 2021-2024  Simon Ruderich
5
6 package config
7
8 import (
9         "fmt"
10         "os"
11         "strings"
12
13         "gopkg.in/yaml.v2"
14 )
15
16 type Hosts struct {
17         List []*Host
18         Map  map[string]*Host
19 }
20
21 type Host struct {
22         Name string `yaml:"name"`
23
24         SshUser string `yaml:"ssh_user"`
25 }
26
27 func LoadHosts() (*Hosts, error) {
28         const path = "hosts.yaml"
29
30         var hostList []*Host
31         x, err := os.ReadFile(path)
32         if err != nil {
33                 return nil, err
34         }
35         err = yaml.UnmarshalStrict(x, &hostList)
36         if err != nil {
37                 return nil, fmt.Errorf("%s: failed to load: %v", path, err)
38         }
39
40         hostMap := make(map[string]*Host)
41         for _, x := range hostList {
42                 errPrefix := fmt.Sprintf("%s: host %q:", path, x.Name)
43                 if x.Name == GroupAll {
44                         return nil, fmt.Errorf(
45                                 "%s conflict with pre-defined group %q",
46                                 errPrefix, x.Name)
47                 }
48                 if strings.HasPrefix(x.Name, GroupDetectedPrefix) {
49                         return nil, fmt.Errorf(
50                                 "%s name must not start with %q "+
51                                         "(reserved for detected groups)",
52                                 errPrefix, GroupDetectedPrefix)
53                 }
54                 if strings.Contains(x.Name, GroupSpecialSeparator) {
55                         return nil, fmt.Errorf(
56                                 "%s name must not contain %q",
57                                 errPrefix, GroupSpecialSeparator)
58                 }
59
60                 if hostMap[x.Name] != nil {
61                         return nil, fmt.Errorf("%s host name already exists",
62                                 errPrefix)
63                 }
64                 hostMap[x.Name] = x
65         }
66
67         return &Hosts{
68                 List: hostList,
69                 Map:  hostMap,
70         }, nil
71 }