4.7 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
core/go-ansible is a pure Go Ansible playbook engine. It parses YAML playbooks, inventories, and roles, then executes tasks on remote hosts via SSH. 42 module handler implementations (plus 3 community modules), Jinja2-compatible templating, privilege escalation (become), and event-driven callbacks. This is a library — there is no standalone binary. The CLI integration lives in cmd/ansible/ and is compiled as part of the core CLI binary.
Build & Test
go build ./... # verify compilation
go test ./... # run all tests
go test -race ./... # with race detection
go test -run TestParsePlaybook_Good_SimplePlay # single test
go test -v ./... # verbose output
go work sync # if in a Go workspace
No SSH access is needed for tests — the suite uses a mock SSH client (mock_ssh_test.go).
Architecture
Single flat ansible package with four layers:
Playbook YAML ──► Parser ──► []Play ──► Executor ──► Module Handlers ──► SSH Client ──► Remote Host
│ │
Inventory YAML ──► Parser ──► Inventory Callbacks (OnPlayStart, OnTaskEnd, ...)
types.go— Core structs (Playbook,Play,Task,TaskResult,Inventory,Host,Facts) andKnownModulesregistry (96 entries: both FQCNansible.builtin.*and short forms, plus compatibility aliases).parser.go— YAML parsing for playbooks, inventories, tasks, and roles. CustomTask.UnmarshalYAMLscans map keys againstKnownModulesto extract the module name and args (since Ansible embeds the module name as a YAML key, not a fixed field). Free-form syntax (shell: echo hello) is stored asArgs["_raw_params"]. Iterator variants (ParsePlaybookIter,ParseTasksIter, etc.) returniter.Seqvalues.executor.go— Orchestration engine: host resolution from inventory, play execution order (gather facts → pre_tasks → roles → tasks → post_tasks → notified handlers),when:condition evaluation,{{ }}Jinja2-style templating with filter support, loop execution, block/rescue/always, handler notification.modules.go— 50 module handler implementations dispatched via aswitchon the normalised module name. Each handler extracts args viagetStringArg/getBoolArg, constructs shell commands, runs them via SSH, and returns aTaskResult.ssh.go— SSH client with lazy connection, auth chain (key file → default keys → password),known_hostsverification, become/sudo wrapping, file transfer viacat >piped through stdin.cmd/ansible/— CLI command registration viacore/cli. Providesansible <playbook>andansible test <host>subcommands with flags for inventory, limit, tags, extra-vars, verbosity, and check mode.
Adding a New Module
- Add both FQCN and short form to
KnownModulesintypes.go - Add the dispatch case in
executeModuleswitch inmodules.go - Implement
module{Name}(ctx, client, args)method onExecutorinmodules.go - Write tests in the appropriate
modules_*_test.gofile using mock SSH infrastructure
If adding new YAML keys to Task, update the knownKeys map in Task.UnmarshalYAML (parser.go) to prevent them being mistaken for module names.
Test Organisation
| File | Coverage |
|---|---|
types_test.go |
YAML unmarshalling for Task, RoleRef, Inventory, Facts |
parser_test.go |
Playbook, inventory, and task file parsing |
executor_test.go |
Executor lifecycle, conditions, templating, loops, tags |
ssh_test.go |
SSH client construction and defaults |
modules_cmd_test.go |
Command modules: shell, command, raw, script |
modules_file_test.go |
File modules: copy, template, file, lineinfile, stat, slurp, fetch, get_url |
modules_svc_test.go |
Service modules: service, systemd, user, group |
modules_infra_test.go |
Infrastructure modules: apt, pip, git, unarchive, ufw, docker_compose |
modules_adv_test.go |
Advanced modules: debug, fail, assert, set_fact, pause, wait_for, uri, blockinfile, cron, hostname, sysctl, reboot |
Coding Standards
- UK English in comments and documentation (colour, organisation, centre)
- Test naming:
_Good(happy path),_Bad(expected errors),_Ugly(edge cases/panics) - Use
coreerr.E(scope, message, err)fromgo-logfor all errors in production code (neverfmt.Errorf) - Tests use
testify/assert(soft) andtestify/require(hard) - Licence: EUPL-1.2