line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Chef::Knife::Cmd; |
2
|
6
|
|
|
6
|
|
591946
|
use feature qw/say/; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
558
|
|
3
|
6
|
|
|
6
|
|
2774
|
use Moo; |
|
6
|
|
|
|
|
58835
|
|
|
6
|
|
|
|
|
26
|
|
4
|
|
|
|
|
|
|
|
5
|
6
|
|
|
6
|
|
9306
|
use Chef::Knife::Cmd::Client; |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
192
|
|
6
|
6
|
|
|
6
|
|
2623
|
use Chef::Knife::Cmd::EC2; |
|
6
|
|
|
|
|
17
|
|
|
6
|
|
|
|
|
167
|
|
7
|
6
|
|
|
6
|
|
2487
|
use Chef::Knife::Cmd::Node; |
|
6
|
|
|
|
|
16
|
|
|
6
|
|
|
|
|
189
|
|
8
|
6
|
|
|
6
|
|
2618
|
use Chef::Knife::Cmd::Vault; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
194
|
|
9
|
6
|
|
|
6
|
|
2477
|
use Chef::Knife::Cmd::Search; |
|
6
|
|
|
|
|
16
|
|
|
6
|
|
|
|
|
193
|
|
10
|
6
|
|
|
6
|
|
2525
|
use Chef::Knife::Cmd::DataBag; |
|
6
|
|
|
|
|
85
|
|
|
6
|
|
|
|
|
158
|
|
11
|
6
|
|
|
6
|
|
2549
|
use Shell::Carapace; |
|
6
|
|
|
|
|
2004
|
|
|
6
|
|
|
|
|
157
|
|
12
|
6
|
|
|
6
|
|
2417
|
use String::ShellQuote; |
|
6
|
|
|
|
|
4354
|
|
|
6
|
|
|
|
|
394
|
|
13
|
6
|
|
|
6
|
|
2135
|
use JSON::MaybeXS; |
|
6
|
|
|
|
|
27202
|
|
|
6
|
|
|
|
|
3594
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = "0.15"; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 NAME |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Chef::Knife::Cmd - A small wrapper around the Chef 'knife' command line utility |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 SYNOPSIS |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
use Chef::Knife::Cmd; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# See Shell::Carapace for details about the callback attribute |
26
|
|
|
|
|
|
|
my $knife = Chef::Knife::Cmd->new( |
27
|
|
|
|
|
|
|
callback => sub { ... }, # optional. useful for logging realtime output; |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# knife bootstrap |
31
|
|
|
|
|
|
|
$knife->bootstrap($fqdn, %options); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# knife client |
34
|
|
|
|
|
|
|
$knife->client->delete($client, %options); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# knife ec2 |
37
|
|
|
|
|
|
|
$knife->ec2->server->list(%options); |
38
|
|
|
|
|
|
|
$knife->ec2->server->create(%options); |
39
|
|
|
|
|
|
|
$knife->ec2->server->delete(\@nodes, %options); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# knife node |
42
|
|
|
|
|
|
|
$knife->node->show($node, %options); |
43
|
|
|
|
|
|
|
$knife->node->list($node, %options); |
44
|
|
|
|
|
|
|
$knife->node->create($node, %options); |
45
|
|
|
|
|
|
|
$knife->node->delete($node, %options); |
46
|
|
|
|
|
|
|
$knife->node->flip($node, $environment, %options); |
47
|
|
|
|
|
|
|
$knife->node->from->file($file, %options); |
48
|
|
|
|
|
|
|
$knife->node->run_list->add($node, \@entries, %options); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# knife vault commands |
51
|
|
|
|
|
|
|
# hint: use $knife->vault->item() instead of $knife->vault->show() |
52
|
|
|
|
|
|
|
$knife->vault->list(%options); |
53
|
|
|
|
|
|
|
$knife->vault->show($vault, $item_name, %options); |
54
|
|
|
|
|
|
|
$knife->vault->create($vault, $item, $values, %options); |
55
|
|
|
|
|
|
|
$knife->vault->update($vault, $item, $values, %options); |
56
|
|
|
|
|
|
|
$knife->vault->delete($vault, $item, %options); |
57
|
|
|
|
|
|
|
$knife->vault->remove($vault, $item, $values, %options); |
58
|
|
|
|
|
|
|
$knife->vault->download($vault, $item, $path, %options); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# knife search commands |
61
|
|
|
|
|
|
|
$knife->search->node($query, %options); |
62
|
|
|
|
|
|
|
$knife->search->client($query, %options); |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# knife data bag commands |
65
|
|
|
|
|
|
|
$knife->data_bag->show($data_bag, %options); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# All methods return the output of the cmd as a string |
68
|
|
|
|
|
|
|
my $out = $knife->node->show('mynode'); |
69
|
|
|
|
|
|
|
# => |
70
|
|
|
|
|
|
|
# Node Name: mynode |
71
|
|
|
|
|
|
|
# Environment: production |
72
|
|
|
|
|
|
|
# FQDN: |
73
|
|
|
|
|
|
|
# IP: 12.34.56.78 |
74
|
|
|
|
|
|
|
# Run List: ... |
75
|
|
|
|
|
|
|
# ... |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# All methods return the output of the cmd as a hashref when '--format json' is used |
78
|
|
|
|
|
|
|
my $hashref = $knife->node->show('mynode', format => 'json'); |
79
|
|
|
|
|
|
|
# => |
80
|
|
|
|
|
|
|
# { |
81
|
|
|
|
|
|
|
# name => "mynode", |
82
|
|
|
|
|
|
|
# chef_environment => "production", |
83
|
|
|
|
|
|
|
# run_list => [...], |
84
|
|
|
|
|
|
|
# ... |
85
|
|
|
|
|
|
|
# } |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 DESCRIPTION |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
This module is a small wrapper around the Chef 'knife' command line utility. |
91
|
|
|
|
|
|
|
It would be awesome if this module used the Chef server API, but this module is |
92
|
|
|
|
|
|
|
not that awesome. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Some things worth knowing about this module: |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=over 4 |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item Return vaules |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
All commands return the output of the knife command. |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item Logging |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
If you wish to log output, you should do so via the 'callback' attribute. See |
105
|
|
|
|
|
|
|
Shell::Carapace for more details. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item Exceptions |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
If a knife command fails, an exception is thrown. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=back |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=cut |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
has noop => (is => 'rw', default => sub { 0 }); |
116
|
|
|
|
|
|
|
has shell => (is => 'lazy'); |
117
|
|
|
|
|
|
|
has format => (is => 'rw'); |
118
|
|
|
|
|
|
|
has _json_flag => (is => 'rw'); |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
has callback => (is => 'rw'); |
121
|
|
|
|
|
|
|
has output => (is => 'rw'); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
has client => (is => 'lazy'); |
124
|
|
|
|
|
|
|
has ec2 => (is => 'lazy'); |
125
|
|
|
|
|
|
|
has node => (is => 'lazy'); |
126
|
|
|
|
|
|
|
has vault => (is => 'lazy'); |
127
|
|
|
|
|
|
|
has search => (is => 'lazy'); |
128
|
|
|
|
|
|
|
has data_bag => (is => 'lazy'); |
129
|
|
|
|
|
|
|
|
130
|
1
|
|
|
1
|
|
1619
|
sub _build_client { Chef::Knife::Cmd::Client->new(knife => shift) } |
131
|
1
|
|
|
1
|
|
1624
|
sub _build_ec2 { Chef::Knife::Cmd::EC2->new(knife => shift) } |
132
|
1
|
|
|
1
|
|
1829
|
sub _build_node { Chef::Knife::Cmd::Node->new(knife => shift) } |
133
|
1
|
|
|
1
|
|
1586
|
sub _build_vault { Chef::Knife::Cmd::Vault->new(knife => shift) } |
134
|
0
|
|
|
0
|
|
0
|
sub _build_search { Chef::Knife::Cmd::Search->new(knife => shift) } |
135
|
0
|
|
|
0
|
|
0
|
sub _build_data_bag { Chef::Knife::Cmd::DataBag->new(knife => shift) } |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub _build_shell { |
138
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
139
|
|
|
|
|
|
|
my $cb = sub { |
140
|
0
|
|
|
0
|
|
0
|
my ($type, $message) = @_; |
141
|
0
|
0
|
|
|
|
0
|
if ($type ne 'error') { |
142
|
0
|
0
|
|
|
|
0
|
if ($type eq 'command') { |
143
|
0
|
|
|
|
|
0
|
$self->output(''); |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
else { |
146
|
0
|
|
|
|
|
0
|
my $output = ''; |
147
|
0
|
0
|
|
|
|
0
|
$output .= $self->output . "\n" if $self->output; |
148
|
0
|
|
|
|
|
0
|
$output .= $message; |
149
|
0
|
|
|
|
|
0
|
$self->output($output); |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
} |
152
|
0
|
0
|
|
|
|
0
|
$self->callback->(@_) if $self->callback; |
153
|
0
|
|
|
|
|
0
|
}; |
154
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
0
|
return Shell::Carapace->shell(callback => $cb); |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub bootstrap { |
159
|
1
|
|
|
1
|
|
1735
|
my ($self, $fqdn, %options) = @_; |
160
|
1
|
|
|
|
|
6
|
my @opts = $self->handle_options(%options); |
161
|
1
|
|
|
|
|
5
|
my @cmd = (qw/knife bootstrap/, $fqdn, @opts); |
162
|
1
|
|
|
|
|
3
|
$self->run(@cmd); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub handle_options { |
166
|
19
|
|
|
19
|
0
|
458
|
my ($self, %options) = @_; |
167
|
|
|
|
|
|
|
|
168
|
19
|
50
|
0
|
|
|
99
|
$options{format} //= $self->format if $self->format; |
169
|
|
|
|
|
|
|
|
170
|
19
|
50
|
33
|
|
|
77
|
$options{format} && $options{format} eq 'json' |
171
|
|
|
|
|
|
|
? $self->_json_flag(1) |
172
|
|
|
|
|
|
|
: $self->_json_flag(0); |
173
|
|
|
|
|
|
|
|
174
|
19
|
|
|
|
|
16
|
my @opts; |
175
|
19
|
|
|
|
|
50
|
for my $option (sort keys %options) { |
176
|
19
|
|
|
|
|
23
|
my $value = $options{$option}; |
177
|
19
|
|
|
|
|
32
|
$option =~ s/_/-/g; |
178
|
|
|
|
|
|
|
|
179
|
19
|
|
|
|
|
27
|
push @opts, "--$option"; |
180
|
19
|
100
|
|
|
|
41
|
push @opts, $value if $value ne "1"; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
19
|
|
|
|
|
62
|
return @opts; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub run { |
187
|
19
|
|
|
19
|
0
|
439
|
my ($self, @cmds) = @_; |
188
|
19
|
50
|
|
|
|
96
|
return shell_quote @cmds if $self->noop; |
189
|
0
|
|
|
|
|
|
$self->shell->run(@cmds); |
190
|
0
|
|
|
|
|
|
my $out = $self->output; |
191
|
0
|
0
|
|
|
|
|
return JSON->new->utf8->decode($out) if $self->_json_flag; |
192
|
0
|
|
|
|
|
|
return $out; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
1; |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=head1 SEE ALSO |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=over 4 |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=item L<Capture::Tiny::Extended> |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item L<Capture::Tiny> |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item L<IPC::System::Simple> |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=back |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=head1 LICENSE |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
212
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=head1 AUTHOR |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
Eric Johnson E<lt>eric.git@iijo.orgE<gt> |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=cut |