Go library for Parsing Ansible inventory files

Overview

aini

Go library for Parsing Ansible inventory files.
We are trying to follow the logic of Ansible parser as close as possible.

Documentation on ansible inventory files can be found here:
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

Supported features:

  • Variables
  • Host patterns
  • Nested groups

Public API

package aini // import "github.com/relex/aini"


TYPES

type Group struct {
        Name     string
        Vars     map[string]string
        Hosts    map[string]*Host
        Children map[string]*Group
        Parents  map[string]*Group
}
    Group represents ansible group

func GroupMapListValues(mymap map[string]*Group) []*Group
    GroupMapListValues transforms map of Groups into Group list

type Host struct {
        Name   string
        Port   int
        Vars   map[string]string
        Groups map[string]*Group
}
    Host represents ansible host

func HostMapListValues(mymap map[string]*Host) []*Host
    HostMapListValues transforms map of Hosts into Host list

type InventoryData struct {
        Groups map[string]*Group
        Hosts  map[string]*Host
}
    InventoryData contains parsed inventory representation Note: Groups and
    Hosts fields contain all the groups and hosts, not only top-level

func Parse(r io.Reader) (*InventoryData, error)
    Parse using some Reader

func ParseFile(f string) (*InventoryData, error)
    ParseFile parses Inventory represented as a file

func ParseString(input string) (*InventoryData, error)
    ParseString parses Inventory represented as a string

func (inventory *InventoryData) GroupsToLower()
    GroupsToLower transforms all group names to lowercase

func (inventory *InventoryData) HostsToLower()
    HostsToLower transforms all host names to lowercase

func (inventory *InventoryData) Match(m string) []*Host
    Match looks for a hosts that match the pattern

func (inventory *InventoryData) Reconcile()
    Reconcile ensures inventory basic rules, run after updates

Usage example

import (
    "strings"
    
    "github.com/relex/aini"
)

func main() {
    // Load from string example
    inventoryReader := strings.NewReader(`
	host1:2221
	[web]
	host2 ansible_ssh_user=root
    `)
    var inventory InventoryData = aini.Parse(inventoryReader)

    // Querying hosts
    _ = inventory.Hosts["host1"].Name == "host1"  // true
    _ = inventory.Hosts["host1"].Port == 2221     // true
    _ = inventory.Hosts["host2"].Name == "host2"] // true
    _ = inventory.Hosts["host2"].Post == 22]      // true
    
    _ = len(inventory.Hosts["host1"].Groups) == 2 // all, ungrouped
    _ = len(inventory.Hosts["host2"].Groups) == 2 // all, web
    
    _ = len(inventory.Match("host*")) == 2        // host1, host2

    _ = // Querying groups
    _ = inventory.Groups["web"].Hosts[0].Name == "host2" // true
    _ = len(inventory.Groups["all"].Hosts) == 2          // true
}
Comments
  • Host ranges not working as expected

    Host ranges not working as expected

    I stumbled upon your library when working on a little inventory CLI and I think I found an error.

    To illustrate I wrote a minimal example:

    package main
    
    import (
    	"fmt"
    	"strings"
    
    	"github.com/relex/aini"
    )
    
    func main() {
    	// Load from string example
    	inventoryReader := strings.NewReader(`foo-[1:2]-[a:c]-bar`)
    	inventory, _ := aini.Parse(inventoryReader)
    
    	for host, _ := range inventory.Hosts {
    		fmt.Println(host)
    	}
    }
    
    

    The output of this when run through go run main.go is as follows:

    foo-1-[a:c]-bar
    foo-2-[a:c]-bar
    

    I think this is incorrect and should result in this output instead:

    foo-1-a-bar
    foo-1-b-bar
    foo-1-c-bar
    foo-2-a-bar
    foo-2-b-bar
    foo-2-c-bar
    
    opened by href 6
  • "ungrouped" always contains all hosts even though they belong to another group.

    Hi,

    great library!

    For my use case I don't need "all" and "ungrouped" - so its not a major thing for me BUT...

    I am iterating over the groups and outputting all group names and their respective hosts, I noticed that ungrouped is output with all hosts. According to the docs at ansible, ungrouped should only contain hosts that don't belong to any other group.

    Here is a short sample of my quick and dirty method for demonstrating..

    	for _, g := range inventory.Groups {
    		_, _ = datawriter.WriteString("[" + g.Name + "]\n")
    		for _, h := range g.Hosts {
    			_, _ = datawriter.WriteString(h.Name + "\n")
    
    .....
    

    So basically I get a list of groups and their respective hosts, works great! But I also get an "ungrouped" group but it contains ALL hosts

    Is this correct? I would have suspected that it should be empty as all my hosts belong to another group.

    Thanks in advance

    opened by iangregsondev 3
  • How to use your library in go < 1.16?

    How to use your library in go < 1.16?

    I'm on a mainstream release that only supports Go 1.15. It seems that your library has a go 1.16 dependency somewhere given the error when trying to get the library installed:

    go get github.com/relex/aini package io/fs: unrecognized import path "io/fs": import path does not begin with hostname

    Can you consider making the library compatible to Go versions < 1.16? (not sure how much you depend on io/fs, but if you could remove the dependency without huge effort would be great?)

    opened by moudsen 1
  • Support for group_vars and host_vars

    Support for group_vars and host_vars

    This PR adds support for loading external variables from group_vars and host_vars directories. Also:

    • Refactor tests to use testify
    • Add few missing tests for public API functions
    • Fix warnings reported by the new Go

    Fixes #3 Fixes #4

    opened by bemyak 1
  • [Feature Request] Parse inventory yaml files as well

    [Feature Request] Parse inventory yaml files as well

    Hi.

    Is there any chance to get a possibility of parsing YAML files instead of INIs?

    Thanks in advance!

    [EDITED] This is about Inventories in YAML format.

    opened by thunder-spb 4
Owner
Relex
Relex
Redis inventory is a tool to analyse Redis memory usage by key patterns and displaying it hierarchically

Redis inventory is a tool to analyse Redis memory usage by key patterns and displaying it hierarchically. The name is inspired by "Disk Inventory X" tool doing similar analysis for disk usage.

Aleks Obukhov 185 Sep 14, 2022
Wishbox - Wishlist using netbox as inventory source

Wishbox Generate a wishlist directory based on your netbox inventory. How does i

Jonah 10 Aug 11, 2022
Flag is a simple but powerful command line option parsing library for Go support infinite level subcommand

Flag Flag is a simple but powerful commandline flag parsing library for Go. Documentation Documentation can be found at Godoc Supported features bool

null 122 Sep 1, 2022
Idiomatic Go input parsing with subcommands, positional values, and flags at any position. No required project or package layout and no external dependencies.

Sensible and fast command-line flag parsing with excellent support for subcommands and positional values. Flags can be at any position. Flaggy has no

Eric Greer 812 Sep 26, 2022
Struct-based argument parsing in Go

go-arg Struct-based argument parsing for Go Declare command line arguments for your program by defining a struct. var args struct { Foo string Bar b

Alex Flint 1.4k Sep 21, 2022
Generate flags by parsing structures

Flags based on structures. The sflags package uses structs, reflection and struct field tags to allow you specify command line options. It supports di

null 141 Sep 26, 2022
elf binary parsing utility written in Go.

What is it ? go-readelf is a small elf binary parser currently capable of printing relocation entries, elf header, sections and Symbols. It utilizes G

null 57 Aug 31, 2022
A rich tool for parsing flags and values in pure Golang

A rich tool for parsing flags and values in pure Golang. No additional library is required and you can use everywhere.

ALi.w 14 Jan 25, 2022
Package varflag implements command-line flag parsing into vars.Variables for easy type handling with additional flag types.

varflag Package flag implements command-line flag parsing into vars.Variables for easy type handling with additional flag types. varflag Flags String

Marko Kungla 2 Aug 2, 2022
Rdelf2json - CLI application for parsing ELF and converting to json

rdelf2json CLI application for parsing ELF and converting to json Install go ins

kinpoko 0 Jan 22, 2022
🚀 Platform providing a powerful and fast public script parsing API dedicated to the Skript community.

SkriptMC-Parser is currently a prototype in the early stages of development of a system that allows the Skript community to test their scripts via a public API for potential errors or warnings. This is a quick and easy way to check your scripts without having to set up a Spigot server on your environment.

Romain 0 Mar 3, 2022
lls is lightweight ls. Using lls, you can get a list of files in a directory that contains a large number of files.

lls lls is lightweight ls. Using lls, you can get a list of files in a directory that contains a large number of files. How? You allocate a buffer for

Tatsuya Kaneko 57 Aug 31, 2022
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Geet Sethi 1 Mar 27, 2022
tinygo-used-files is a CLI tool that lists only the files to be built as specified by buildtag.

tinygo-used-files is a CLI tool that lists only the files to be built as specified by buildtag.

sago35 0 Feb 6, 2022
Related is a simple cli utility tool to create files or a group of files.

Related - Create files based on individual definitions or groups Related helps with common file-creation-based tasks. You can predefine single types a

Andrej Benz 3 Apr 16, 2022
Easy to use library and CLI utility to generate Go struct from CSV files.

csv2struct Easy to use library and CLI utility to generate Go struct from CSV files. As a benefit, it's fully compatible with csvutil. So, structs gen

Ivan Maliovaniy 11 Aug 19, 2022
A Go library, used to search and replace relative paths in go.mod files to absolute paths.

gomod-absolutizer gomod-absolutizer is a Go library, used to search and replace relative paths in go.mod files to absolute paths. The library is used

JFrog Ltd. 3 Mar 11, 2022
:zap: boilerplate template manager that generates files or directories from template repositories

Boilr Are you doing the same steps over and over again every time you start a new programming project? Boilr is here to help you create projects from

Tamer Tas 1.5k Sep 25, 2022
Rem is a CLI trash which makes it ridiculously easy to recover files.

Rem is a CLI trash which makes it ridiculously easy to recover files. We've all had that moment when we've deleted something we realised we shouldn't have. It sucks. Let's fix that!

Ishan Goel 44 Aug 10, 2022