{"id":15151630,"url":"https://github.com/relex/aini","last_synced_at":"2025-04-05T15:10:01.253Z","repository":{"id":48591618,"uuid":"234083003","full_name":"relex/aini","owner":"relex","description":"Go library for Parsing Ansible inventory files","archived":false,"fork":false,"pushed_at":"2024-07-29T13:20:25.000Z","size":91,"stargazers_count":100,"open_issues_count":2,"forks_count":13,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-29T14:11:22.481Z","etag":null,"topics":["ansible","ansible-inventory","go","golang","parser","parser-library"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/relex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-15T13:08:41.000Z","updated_at":"2024-08-21T02:13:44.000Z","dependencies_parsed_at":"2024-04-30T10:47:03.156Z","dependency_job_id":"fb2fbb4a-08e5-4cf5-ba33-1aed8e8a202b","html_url":"https://github.com/relex/aini","commit_stats":{"total_commits":20,"total_committers":3,"mean_commits":6.666666666666667,"dds":"0.44999999999999996","last_synced_commit":"b67a1e990856ac488c888cab9bfcda9fe62015df"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relex%2Faini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relex%2Faini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relex%2Faini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/relex%2Faini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/relex","download_url":"https://codeload.github.com/relex/aini/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353749,"owners_count":20925329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-inventory","go","golang","parser","parser-library"],"created_at":"2024-09-26T15:04:36.350Z","updated_at":"2025-04-05T15:10:01.233Z","avatar_url":"https://github.com/relex.png","language":"Go","readme":"# aini\n\nGo library for Parsing Ansible inventory files.  \nWe are trying to follow the logic of Ansible parser as close as possible.\n\nDocumentation on ansible inventory files can be found here:  \nhttps://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html\n\n## Supported features:\n- [X] Variables\n- [X] Host patterns\n- [X] Nested groups\n- [X] Load variables from `group_vars` and `host_vars`\n\n## Public API\n```godoc\npackage aini // import \"github.com/relex/aini\"\n\n\nFUNCTIONS\n\nfunc MatchGroups(groups map[string]*Group, pattern string) (map[string]*Group, error)\n    MatchGroups looks for groups that match the pattern\n\nfunc MatchHosts(hosts map[string]*Host, pattern string) (map[string]*Host, error)\n    MatchHosts looks for hosts that match the pattern\n\nfunc MatchVars(vars map[string]string, pattern string) (map[string]string, error)\n    MatchVars looks for vars that match the pattern\n\n\nTYPES\n\ntype Group struct {\n        Name     string\n        Vars     map[string]string\n        Hosts    map[string]*Host\n        Children map[string]*Group\n        Parents  map[string]*Group\n\n        // Has unexported fields.\n}\n    Group represents ansible group\n\nfunc GroupMapListValues(mymap map[string]*Group) []*Group\n    GroupMapListValues transforms map of Groups into Group list in lexical order\n\nfunc (group *Group) MatchHosts(pattern string) (map[string]*Host, error)\n    MatchHosts looks for hosts that match the pattern\n\nfunc (group *Group) MatchVars(pattern string) (map[string]string, error)\n    MatchVars looks for vars that match the pattern\n\nfunc (group Group) String() string\n\ntype Host struct {\n        Name   string\n        Port   int\n        Vars   map[string]string\n        Groups map[string]*Group\n\n        // Has unexported fields.\n}\n    Host represents ansible host\n\nfunc HostMapListValues(mymap map[string]*Host) []*Host\n    HostMapListValues transforms map of Hosts into Host list in lexical order\n\nfunc (host *Host) MatchGroups(pattern string) (map[string]*Group, error)\n    MatchGroups looks for groups that match the pattern\n\nfunc (host *Host) MatchVars(pattern string) (map[string]string, error)\n    MatchVars looks for vars that match the pattern\n\nfunc (host Host) String() string\n\ntype InventoryData struct {\n        Groups map[string]*Group\n        Hosts  map[string]*Host\n}\n    InventoryData contains parsed inventory representation Note: Groups and\n    Hosts fields contain all the groups and hosts, not only top-level\n\nfunc Parse(r io.Reader) (*InventoryData, error)\n    Parse using some Reader\n\nfunc ParseFile(f string) (*InventoryData, error)\n    ParseFile parses Inventory represented as a file\n\nfunc ParseString(input string) (*InventoryData, error)\n    ParseString parses Inventory represented as a string\n\nfunc (inventory *InventoryData) AddVars(path string) error\n    AddVars take a path that contains group_vars and host_vars directories and\n    adds these variables to the InventoryData\n\nfunc (inventory *InventoryData) AddVarsLowerCased(path string) error\n    AddVarsLowerCased does the same as AddVars, but converts hostnames and\n    groups name to lowercase. Use this function if you've executed\n    `inventory.HostsToLower` or `inventory.GroupsToLower`\n\nfunc (inventory *InventoryData) GroupsToLower()\n    GroupsToLower transforms all group names to lowercase\n\nfunc (inventory *InventoryData) HostsToLower()\n    HostsToLower transforms all host names to lowercase\n\nfunc (inventory *InventoryData) Match(pattern string) []*Host\n    Match looks for hosts that match the pattern Deprecated: Use `MatchHosts`,\n    which does proper error handling\n\nfunc (inventory *InventoryData) MatchGroups(pattern string) (map[string]*Group, error)\n    MatchGroups looks for groups that match the pattern\n\nfunc (inventory *InventoryData) MatchHosts(pattern string) (map[string]*Host, error)\n    MatchHosts looks for hosts that match the pattern\n\nfunc (inventory *InventoryData) Reconcile()\n    Reconcile ensures inventory basic rules, run after updates. After initial\n    inventory file processing, only direct relationships are set.\n\n    This method:\n\n        * (re)sets Children and Parents for hosts and groups\n        * ensures that mandatory groups exist\n        * calculates variables for hosts and groups\n\n```\n\n## Usage example\n```go\nimport (\n    \"strings\"\n    \n    \"github.com/relex/aini\"\n)\n\nfunc main() {\n    // Load from string example\n    inventoryReader := strings.NewReader(`\n\thost1:2221\n\t[web]\n\thost2 ansible_ssh_user=root\n    `)\n    var inventory InventoryData = aini.Parse(inventoryReader)\n\n    // Querying hosts\n    _ = inventory.Hosts[\"host1\"].Name == \"host1\"  // true\n    _ = inventory.Hosts[\"host1\"].Port == 2221     // true\n    _ = inventory.Hosts[\"host2\"].Name == \"host2\"] // true\n    _ = inventory.Hosts[\"host2\"].Post == 22]      // true\n    \n    _ = len(inventory.Hosts[\"host1\"].Groups) == 2 // all, ungrouped\n    _ = len(inventory.Hosts[\"host2\"].Groups) == 2 // all, web\n    \n    _ = len(inventory.Match(\"host*\")) == 2        // host1, host2\n\n    _ = // Querying groups\n    _ = inventory.Groups[\"web\"].Hosts[0].Name == \"host2\" // true\n    _ = len(inventory.Groups[\"all\"].Hosts) == 2          // true\n}\n```\n\n## Command-line Tool\n\n```bash\ngo install github.com/relex/aini/cmd/ainidump@latest\n```\n\n#### Dump entire inventory\n\n```bash\nainidump ~/my-playbook/inventory/ansible-hosts\n```\n\nHost and group variable files in the inventory directory are always loaded. The result is in JSON:\n- Host's groups and Group's parents are ordered by level from bottom to top\n- Rest are ordered by names\n\n```json\n{\n    \"Hosts\": [\n        {\n            \"Name\": \"myhost1.domain\",\n            \"Groups\": [\n                \"myhosts\",\n                \"companyhosts\",\n                \"india\",\n                \"all\"\n            ],\n            \"Vars\": {\n                \"ansible_host\": \"1.2.3.4\",\n                \"region\": \"india\"\n            }\n        },\n        {\n            \"Name\": \"myhost2.domain\",\n            // ...\n        }\n    ],\n    \"Groups\": [\n        {\n            \"Name\": \"companyhosts\",\n            \"Parents\": [\n                \"india\",\n                \"all\"\n            ],\n            \"Descendants\": [\n                \"myhosts\",\n                \"otherhosts\"\n            ],\n            \"Hosts\": [\n                \"myhost1.domain\",\n                \"myhost2.domain\",\n                \"myhost3.domain\"\n            ],\n            \"Vars\": {\n                \"region\": \"india\",\n            }\n        }\n    ]\n}\n```\n\n#### Match hosts by patterns\n\nFind hosts matched by Ansible [target patterns](https://docs.ansible.com/ansible/latest/inventory_guide/intro_patterns.html), works for both hostnames and group names.\n\n```bash\nainidump ~/my-playbook/inventory/ansible-hosts 'recent[1-3]:extrahost*:\u0026eu:!finland'\n```\n\nThe result is a dictionary of hosts in the same format above.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelex%2Faini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frelex%2Faini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frelex%2Faini/lists"}