From 82402749e6edecc46d06c06b867fe39b8a3968d6 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sun, 26 Jan 2020 18:42:04 +0100 Subject: First ACL implementation --- util.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 util.go (limited to 'util.go') diff --git a/util.go b/util.go new file mode 100644 index 0000000..30f9681 --- /dev/null +++ b/util.go @@ -0,0 +1,103 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "strings" + + consul "github.com/hashicorp/consul/api" +) + +func dnToConsul(dn string) (string, error) { + if strings.Contains(dn, "/") { + return "", fmt.Errorf("DN %s contains a /", dn) + } + + rdns := strings.Split(dn, ",") + + // Reverse rdns + for i, j := 0, len(rdns)-1; i < j; i, j = i+1, j-1 { + rdns[i], rdns[j] = rdns[j], rdns[i] + } + + return strings.Join(rdns, "/"), nil +} + +func consulToDN(key string) (string, string) { + path := strings.Split(key, "/") + dn := "" + for _, cpath := range path { + if cpath == "" { + continue + } + kv := strings.Split(cpath, "=") + if len(kv) == 2 && kv[0] == "attribute" { + return dn, kv[1] + } + if dn != "" { + dn = "," + dn + } + dn = cpath + dn + } + log.Printf("Consul key %s does not end with attribute=something", key) + panic("TODO don't panic handle this") +} + +func parseValue(value []byte) ([]string, error) { + val := []string{} + err := json.Unmarshal(value, &val) + if err == nil { + return val, nil + } + + val2 := "" + err = json.Unmarshal(value, &val2) + if err == nil { + return []string{val2}, nil + } + + return nil, fmt.Errorf("Not a string or list of strings: %s", value) +} + +func parseConsulResult(data []*consul.KVPair) (map[string]Entry, error) { + aggregator := map[string]Entry{} + + for _, kv := range data { + log.Printf("(parseConsulResult) %s %s", kv.Key, string(kv.Value)) + dn, attr := consulToDN(kv.Key) + if _, exists := aggregator[dn]; !exists { + aggregator[dn] = Entry{} + } + value, err := parseValue(kv.Value) + if err != nil { + return nil, err + } + aggregator[dn][attr] = value + } + + return aggregator, nil +} + +type DNComponent struct { + Type string + Value string +} + +func parseDN(dn string) ([]DNComponent, error) { + rdns := strings.Split(dn, ",") + + ret := []DNComponent{} + + for _, rdn := range rdns { + splits := strings.Split(rdn, "=") + if len(splits) != 2 { + return nil, fmt.Errorf("Wrong DN component: %s (expected type=value)", rdn) + } + ret = append(ret, DNComponent{ + Type: splits[0], + Value: splits[1], + }) + } + return ret, nil +} -- cgit v1.2.3