要安装最新的稳定版本,请运行以下命令:
go get github.com/apenella/[email protected]
github.com/apenella/go-ansible/pkg/adhoc包使您能够运行 ansible adhoc命令。您可以使用这些特殊类型来运行ansible命令:
AnsibleAdhocCmd
是主要的对象类型,它定义了ansible adhoc命令以及如何执行该命令。运行任何ansible ad hoc命令都必须使用 AnsibleAdhocCmd
定义。AnsibleAdhocCmd
有一个参数,用于定义要使用的 Executor
,即启动执行的工作程序。如果未指定Executor,则使用空的 DefaultExecutor
。
AnsibleAdhocOptions
类型的参数在ansible的手册页的Options部分进行了描述,并定义了ansible执行行为的方式以及在哪里可以找到执行配置。
您还可以向 AnsiblePlaybookCmd
提供权限提升选项或连接选项,在github.com/apenella/go-ansible/pkg/options
中定义。
github.com/apenella/go-ansible/pkg/playbook
包允许您运行ansible playbook命令。您可以使用 playbook
类来运行 ansible playbook:
AnsiblePlaybookCmd
是主要的对象类型,它定义了ansible playbook命令以及如何执行它。运行任何ansible playbook命令都必须使用 AnsiblePlaybookCmd
定义。AnsiblePlaybookCmd
有一个参数,用于定义要使用的 Executor
,即启动执行的工作者。如果未指定 Executor
,则使用空的 DefaultExecutor
。
AnsiblePlaybookOptions
类型在ansible playbook的手册页的 Options
部分中描述了这些参数,并定义了ansible playbook执行行为的方式以及在哪里可以找到执行配置。
您还可以向 AnsiblePlaybookCmd
提供在 github.com/apenella/go-ansible/pkg/options
中定义的升级特权选项或连接选项。
执行器是负责运行命令并返回在stdout和stderr上接收到的结果的组件。Go-ansible 在 execute
包下有一个默认的 executor 实现。该执行器名为 DefaultExecute
。
任何执行程序都必须遵守executor接口。
// 具有 Execute(context.Context,[]string,stdoutcallback.StdoutCallbackResultsFunc,...ExecuteOptions) 错误方法的类型满足Executor接口
type Executor interface {
Execute(ctx context.Context, command []string, resultsFunc stdoutcallback.StdoutCallbackResultsFunc, options ...ExecuteOptions) error
}
DefaultExecutor
是在可执行库中定义的执行器。在最基本的设置中,它只将命令标准输出写入系统 stdout,stderr 也是如此,但它很容易扩展管理命令stdout和stderr。为了扩展和更新其行为,它附带了一组 ExecuteOptions
函数,这些函数可以传递给执行器。
// /ExecuteOptions是一个设置执行器选项的函数
type ExecuteOptions func(Executor)
扩展如何将结果返回给用户的另一种方法是使用 transformer
,也可以通过WithTransformers(…results.TransformerFunc)ExecuteOptions
将其添加到 DefaultExecutor
只要 DefaultExecutor
不适合您的需要,您就可以编写自己的 执行器 实现,并将其设置在 AnsiblePlaybookCmd
对象上。AnsiblePlaybookCmd
需要一个实现 Executor
接口的对象。
下面是一个可以由 ExecuteOptions
函数配置的自定义执行器示例。
type MyExecutor struct {
Prefix string
}
// Options method is used as a helper to apply a bunch of options to executor
func (e *MyExecutor) Options(options ...execute.ExecuteOptions) {
// apply all options to the executor
for _, opt := range options {
opt(e)
}
}
// WithPrefix method is used to set the executor prefix attribute
func WithPrefix(prefix string) execute.ExecuteOptions {
return func(e execute.Executor) {
e.(*MyExecutor).Prefix = prefix
}
}
func (e *MyExecutor) Execute(ctx context.Context, command []string, resultsFunc stdoutcallback.StdoutCallbackResultsFunc, options ...execute.ExecuteOptions) error {
// It is possible to apply extra options when Execute is called
for _, opt := range options {
opt(e)
}
// that's a dummy work
fmt.Println(fmt.Sprintf("[%s] %s\n", e.Prefix, "I am MyExecutor and I am doing nothing"))
return nil
}
最后,在下一个片段中,使用自定义执行器执行ansible剧本
// define an instance for the new executor and set the options
exe := &MyExecutor{}
exe.Options(
WithPrefix("Go ansible example"),
)
playbook := &ansibler.AnsiblePlaybookCmd{
Playbook: "site.yml",
ConnectionOptions: ansiblePlaybookConnectionOptions,
Options: ansiblePlaybookOptions,
Exec: exe,
}
playbook.Run(context.TODO())
定义命令执行选项的类型可以在 github.com/apenella/go-ansible/pkg/options
中找到。
AnsibleConnectionOptions
对象的参数在ansible剧本的手册页中的 Connections Options
部分进行了描述,并定义了如何连接到主机。AnsiblePrivilegeEscalationOptions
对象的参数在ansible剧本的手册页中的 Escalation Options
部分进行了描述,并定义了如何使用 become user。可以在go ansible上定义和指定stdout回调方法。您可以在AnsiblePlaybookCmd对象上设置StdoutCallback属性。根据使用的方法,结果由一个或另一个函数管理。管理ansible剧本输出的函数在github.com/apenella/go-ansible/pkg/stdoutallback/results包中定义,并且必须在下一个签名之后定义:
// StdoutCallbackResultsFunc defines a function which manages ansible's stdout callbacks. The function expects a context, a reader that receives the data to be wrote and a writer that defines where to write the data coming from reader, Finally a list of transformers could be passed to update the output coming from the executor.
type StdoutCallbackResultsFunc func(context.Context, io.Reader, io.Writer, ...results.TransformerFunc) error
下面描述了管理 ansible playbook 输出的方法:
transformer是一个函数,其目的是丰富或更新来自执行器的输出,并由类型TransformerFunc
定义。
// TransformerFunc is used to enrich or update messages before to be printed out
type TransformerFunc func(string) string
来自执行器的输出被逐行处理,并在该步骤中应用所有 transformers。results包提供了一组可供使用的转换器,但也可以由您自己定义并通过executor传递。
Prepend
:为输出行设置前缀字符串Append
:为输出行设置后缀字符串LogFormat
:在输出行中包含日期时间前缀IgnoreMessage
:根据作为输入参数接收的模式忽略输出行默认情况下,任何stdout回调结果都由 DefaultStdoutCallbackResults
结果方法管理。该results方法在分隔符字符串之前 ──
当定义了任何转换器时,在stdout上的每一行,并在调用worker函数之前准备好所有转换器,worker函数负责将输出写入io.Writer。
当stdout回调方法被定义为json格式时,输出由 JSONSToutCallbackResults
结果方法管理。该results方法准备工作输出函数使用 IgnoreMessage
转换器来忽略那些非json行。将忽略任何其他转换器,但 JSONSToutCallbackResults
在 JSONSTOUTCallbackResults
函数中,定义了 skipPatterns
数组,其中放置了要忽略的行的匹配表达式。
skipPatterns := []string{
// This pattern skips timer's callback whitelist output
"^[\\s\\t]*Playbook run took [0-9]+ days, [0-9]+ hours, [0-9]+ minutes, [0-9]+ seconds$",
}
JSONSToutCallbackResults
方法将json输出写入 io.Writer
参数。Results
包提供了一个 JSONParser
,它返回一个 AnsiblePlaybokJSONResults
,并在上面保存未打包的json。您可以根据需要操作 AnsibleplaybokJSonResults
对象来实现和格式化json输出。
下面你可以找到一个如何使用go ansible的分步示例,但在 examples文件夹中有更多的示例。
当需要使用go ansible库从Golang应用程序运行ansible剧本时,您必须定义 AnsiblePlaybookCmd,AnsiblePlaybookOptions, AnsiblePlaybookConnectionOptions
如下所示。
AnsiblePlaybookConnectionOptions
,其中定义了如何连接到主机。
可选值: local smart ssh
ansiblePlaybookConnectionOptions := &options.AnsiblePlaybookConnectionOptions{
Connection: "local",
}
AnsiblePlaybookOptions
定义了哪些主机参与 playbook 的执行。
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
Inventory: "127.0.0.1,",
}
AnsiblePlaybookPrivilegeEscalationOptions
在哪里定义了是否使用 become 以及如何做到这一点。
privilegeEscalationOptions := &options.AnsiblePlaybookPrivilegeEscalationOptions{
Become: true,
BecomeMethod: "sudo",
}
AnsiblePlaybookCmd,其中定义了命令执行。
cmd := &playbook.AnsiblePlaybookCmd{
Playbook: "site.yml",
ConnectionOptions: ansiblePlaybookConnectionOptions,
Options: ansiblePlaybookOptions,
PrivilegeEscalationOptions: privilegeEscalationOptions,
}
一旦定义了 AnsiblePlaybookCmd
,就可以使用run方法运行它。虽然没有定义,但使用了具有默认参数的Executor DefaultExecute
err := cmd.Run(context.TODO())
if err != nil {
panic(err)
}
执行的结果如下所示。
──
── PLAY [all] *********************************************************************
──
── TASK [Gathering Facts] *********************************************************
── ok: [127.0.0.1]
──
── TASK [simple-ansibleplaybook] **************************************************
── ok: [127.0.0.1] => {
── "msg": "Your are running 'simple-ansibleplaybook' example"
── }
──
── PLAY RECAP *********************************************************************
── 127.0.0.1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
──
── Playbook run took 0 days, 0 hours, 0 minutes, 0 seconds