diff --git a/modules/meta/influx-token-manipulator/go.mod b/modules/meta/influx-token-manipulator/go.mod new file mode 100644 index 0000000..e49e3d5 --- /dev/null +++ b/modules/meta/influx-token-manipulator/go.mod @@ -0,0 +1,6 @@ +module influx-token-manipulator + +go 1.20 + +require go.etcd.io/bbolt v1.3.7 +require golang.org/x/sys v0.4.0 // indirect diff --git a/modules/meta/influx-token-manipulator/go.sum b/modules/meta/influx-token-manipulator/go.sum new file mode 100644 index 0000000..0fc529b --- /dev/null +++ b/modules/meta/influx-token-manipulator/go.sum @@ -0,0 +1,4 @@ +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/modules/meta/influx-token-manipulator/main.go b/modules/meta/influx-token-manipulator/main.go new file mode 100644 index 0000000..b51d04c --- /dev/null +++ b/modules/meta/influx-token-manipulator/main.go @@ -0,0 +1,106 @@ +package main + +import ( + "encoding/json" + "fmt" + "go.etcd.io/bbolt" + "io/ioutil" + "os" + "regexp" + "strings" +) + +var tokenPaths = map[string]string{ + // Add token secrets here or in separate file +} + +func main() { + if len(os.Args) != 2 { + fmt.Println("Usage: ./influx-token-manipulator \n") + os.Exit(1) + } + + dbPath := os.Args[1] + + db, err := bbolt.Open(dbPath, 0666, nil) + if err != nil { + fmt.Printf("Error opening database: %v\n", err) + } + defer db.Close() + + err = db.Update(func(tx *bbolt.Tx) error { + bucket := tx.Bucket([]byte("authorizationsv1")) + if bucket == nil { + fmt.Println("Bucket 'authorizationsv1' not found.") + os.Exit(1) + } + + return bucket.ForEach(func(k, v []byte) error { + var obj map[string]interface{} + if err := json.Unmarshal(v, &obj); err != nil { + fmt.Printf("Error unmarshalling JSON: %v\n", err) + return nil // Continue processing other rows + } + + description, ok := obj["description"].(string) + if !ok { + return nil // Skip if description is not present + } + + identifierRegex := regexp.MustCompile(`[0-9a-f]{32}`) + match := identifierRegex.FindString(description) + if match == "" { + return nil // Skip if description doesn't match regex + } + + tokenPath, found := tokenPaths[match] + if !found { + return nil // Skip if match is not in lookup + } + delete(tokenPaths, match) // Remove entry from the map + + content, err := ioutil.ReadFile(tokenPath) + if err != nil { + fmt.Printf("Error reading new token file: %v\n", err) + return nil // Continue processing other rows + } + newToken := strings.TrimSpace(string(content)) // Remove leading and trailing whitespace + + oldToken, ok := obj["token"].(string) + if !ok { + fmt.Printf("Skipping invalid token without .token\n") + return nil // Skip if token is not present + } + + if oldToken == newToken { + return nil // Skip if token is already up-to-date + } + + obj["token"] = newToken + updatedValue, err := json.Marshal(obj) + if err != nil { + fmt.Printf("Error marshalling updated JSON: %v\n", err) + return nil // Continue processing other rows + } + + if err := bucket.Put(k, updatedValue); err != nil { + fmt.Printf("Error updating bucket: %v\n", err) + return nil // Continue processing other rows + } + + fmt.Printf("Updated token: '%s'\n", description) + return nil + }) + }) + if err != nil { + fmt.Printf("Error during transaction: %v", err) + } + + // Check if any tokens were not processed + if len(tokenPaths) > 0 { + fmt.Println("Warning: The following tokens were not encountered:") + for token := range tokenPaths { + fmt.Printf("- %s\n", token) + } + } +} diff --git a/modules/meta/influxdb.nix b/modules/meta/influxdb.nix index 37edc84..f0099fb 100644 --- a/modules/meta/influxdb.nix +++ b/modules/meta/influxdb.nix @@ -30,6 +30,20 @@ ; cfg = config.services.influxdb2; + + tokenManipulator = pkgs.buildGoModule rec { + pname = "influx-token-manipulator"; + version = "1.0.0"; + src = ./influx-token-manipulator; + postPatch = '' + sed -i '/Add token secrets here/ r ${ + pkgs.writeText "token-paths" (concatMapStrings + (x: ''"${x.id}": "${x.tokenFile}",''\n'') + (filter (x: x.tokenFile != null) cfg.provision.ensureApiTokens)) + }' main.go + ''; + vendorHash = "sha256-zBZk7JbNILX18g9+2ukiESnFtnIVWhdN/J/MBhIITh8="; + }; in { options.services.influxdb2.provision = { enable = mkEnableOption "initial database setup"; @@ -343,6 +357,12 @@ in { type = types.nullOr types.str; }; + options.tokenFile = mkOption { + type = types.nullOr types.path; + default = null; + description = "The token value. If not given, influx will automatically generate one."; + }; + options.operator = mkOption { description = "Grants all permissions in all organizations."; default = false;