-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrunner.go
186 lines (163 loc) · 4.09 KB
/
runner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package goansible
import (
"encoding/json"
"os/exec"
"sync"
)
type Runner interface {
//execute ansible task
Run() (*Result, error)
//only show ansible task command to run, don't execute
CommandString() string
}
type (
CommonOptions struct {
//inventory hosts path or comma separated host list
Inventory string
//prepend colon-separated path(s) to module library
ModulePath string
//don't make any changes
Check bool
//set additional variables as k:v
ExtraVars map[string]string
//number of parallel processes
Forks int
}
AdHocOptions struct {
CommonOptions
//host pattern
Pattern string
//module name to execute
ModuleName string
//module arguments string, map, or struct
//if use map, free form parameter is actual parameter named 'free_form'.
//but use string, free form parameter is no actual parameter
ModuleArgs interface{}
//async timeout, seconds
BackgroundSeconds int
//async poll interval, seconds
PollInterval int
}
PlaybookOptions struct {
CommonOptions
//playbook file path
Playbook string
//clear the fact cache for every host in inventory
FlushCache bool
//only run plays and tasks tagged with these values
Tags string
}
ConnectionOptions struct {
//ssh key file, use this file to authenticate the connection
PrivateKey string
//connection timeout, seconds
Timeout int
//connection type to use (default=smart)
Connection string
//connect as this user
RemoteUser string
}
PrivilegeOptions struct {
//privilege escalation method to use (default=sudo)
BecomeMethod string
//run operations as this user (default=root)
BecomeUser string
//run operations with become
Become bool
}
)
type (
AdHocRunner struct {
Bin string
Options *AdHocOptions
ConnectionOptions *ConnectionOptions
PrivilegeOptions *PrivilegeOptions
mutex sync.Mutex
}
PlaybookRunner struct {
Bin string
Options *PlaybookOptions
ConnectionOptions *ConnectionOptions
PrivilegeOptions *PrivilegeOptions
mutex sync.Mutex
}
)
type (
//ansible running results
Result struct {
CustomStats map[string]interface{} `json:"custom_stats"`
GlobalCustomStats map[string]interface{} `json:"global_custom_stats"`
Plays []*Play `json:"plays"`
Summary map[string]interface{} `json:"stats"`
}
Play struct {
Play map[string]interface{} `json:"play"`
Tasks []*Task `json:"tasks"`
}
Task struct {
Hosts map[string]interface{} `json:"hosts"`
Task map[string]interface{} `json:"task"`
}
)
func NewAdHocRunner() *AdHocRunner {
return &AdHocRunner{
Options: &AdHocOptions{},
ConnectionOptions: &ConnectionOptions{},
PrivilegeOptions: &PrivilegeOptions{},
}
}
func NewPlaybookRunner() *PlaybookRunner {
return &PlaybookRunner{
Options: &PlaybookOptions{},
ConnectionOptions: &ConnectionOptions{},
PrivilegeOptions: &PrivilegeOptions{},
}
}
func (r *AdHocRunner) Run() (*Result, error) {
return execute(r.command())
}
func (r *AdHocRunner) CommandString() string {
return r.command().String()
}
func (r *AdHocRunner) command() *exec.Cmd {
r.mutex.Lock()
defer r.mutex.Unlock()
cmdArgs := genAdHocCommand(r)
return executor(
cmdArgs[0],
cmdArgs[1:len(cmdArgs)]...,
)
}
func (r *PlaybookRunner) Run() (*Result, error) {
return execute(r.command())
}
func (r *PlaybookRunner) CommandString() string {
return r.command().String()
}
func (r *PlaybookRunner) command() *exec.Cmd {
r.mutex.Lock()
defer r.mutex.Unlock()
cmdArgs := genPlaybookCommand(r)
return executor(
cmdArgs[0],
cmdArgs[1:len(cmdArgs)]...,
)
}
func executor(name string, args ...string) *exec.Cmd {
return exec.Command(name, args...)
}
func execute(cmd *exec.Cmd) (*Result, error) {
output, err := cmd.CombinedOutput()
//returncode
//rc := comm.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
var data Result
err = json.Unmarshal(output, &data)
return &data, err
}
func (r *Result) String() string {
data, err := json.Marshal(r)
if err != nil {
return err.Error()
}
return string(data)
}