line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Chef::Knife::Cmd; |
2
|
6
|
|
|
6
|
|
258710
|
use feature qw/say/; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
515
|
|
3
|
6
|
|
|
6
|
|
2669
|
use Moo; |
|
6
|
|
|
|
|
56161
|
|
|
6
|
|
|
|
|
23
|
|
4
|
|
|
|
|
|
|
|
5
|
6
|
|
|
6
|
|
8263
|
use Chef::Knife::Cmd::Client; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
162
|
|
6
|
6
|
|
|
6
|
|
2120
|
use Chef::Knife::Cmd::EC2; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
141
|
|
7
|
6
|
|
|
6
|
|
2038
|
use Chef::Knife::Cmd::Node; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
141
|
|
8
|
6
|
|
|
6
|
|
1983
|
use Chef::Knife::Cmd::Vault; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
165
|
|
9
|
6
|
|
|
6
|
|
1974
|
use Chef::Knife::Cmd::Search; |
|
6
|
|
|
|
|
8
|
|
|
6
|
|
|
|
|
146
|
|
10
|
6
|
|
|
6
|
|
1940
|
use Chef::Knife::Cmd::DataBag; |
|
6
|
|
|
|
|
62
|
|
|
6
|
|
|
|
|
148
|
|
11
|
6
|
|
|
6
|
|
2362
|
use Shell::Carapace; |
|
6
|
|
|
|
|
1679
|
|
|
6
|
|
|
|
|
121
|
|
12
|
6
|
|
|
6
|
|
2277
|
use String::ShellQuote; |
|
6
|
|
|
|
|
3547
|
|
|
6
|
|
|
|
|
319
|
|
13
|
6
|
|
|
6
|
|
2304
|
use JSON::MaybeXS; |
|
6
|
|
|
|
|
23747
|
|
|
6
|
|
|
|
|
3464
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = "0.13"; |
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
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# knife search commands |
59
|
|
|
|
|
|
|
$knife->search->node($query, %options); |
60
|
|
|
|
|
|
|
$knife->search->client($query, %options); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# knife data bag commands |
63
|
|
|
|
|
|
|
$knife->data_bag->show($data_bag, %options); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# All methods return the output of the cmd as a string |
66
|
|
|
|
|
|
|
my $out = $knife->node->show('mynode'); |
67
|
|
|
|
|
|
|
# => |
68
|
|
|
|
|
|
|
# Node Name: mynode |
69
|
|
|
|
|
|
|
# Environment: production |
70
|
|
|
|
|
|
|
# FQDN: |
71
|
|
|
|
|
|
|
# IP: 12.34.56.78 |
72
|
|
|
|
|
|
|
# Run List: ... |
73
|
|
|
|
|
|
|
# ... |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# All methods return the output of the cmd as a hashref when '--format json' is used |
76
|
|
|
|
|
|
|
my $hashref = $knife->node->show('mynode', format => 'json'); |
77
|
|
|
|
|
|
|
# => |
78
|
|
|
|
|
|
|
# { |
79
|
|
|
|
|
|
|
# name => "mynode", |
80
|
|
|
|
|
|
|
# chef_environment => "production", |
81
|
|
|
|
|
|
|
# run_list => [...], |
82
|
|
|
|
|
|
|
# ... |
83
|
|
|
|
|
|
|
# } |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=head1 DESCRIPTION |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
This module is a small wrapper around the Chef 'knife' command line utility. |
89
|
|
|
|
|
|
|
It would be awesome if this module used the Chef server API, but this module is |
90
|
|
|
|
|
|
|
not that awesome. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
Some things worth knowing about this module: |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=over 4 |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item Return vaules |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
All commands return the output of the knife command. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=item Logging |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
If you wish to log output, you should do so via the 'callback' attribute. See |
103
|
|
|
|
|
|
|
Shell::Carapace for more details. |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=item Exceptions |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
If a knife command fails, an exception is thrown. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=back |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=cut |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
has noop => (is => 'rw', default => sub { 0 }); |
114
|
|
|
|
|
|
|
has shell => (is => 'lazy'); |
115
|
|
|
|
|
|
|
has format => (is => 'rw'); |
116
|
|
|
|
|
|
|
has _json_flag => (is => 'rw'); |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
has callback => (is => 'rw'); |
119
|
|
|
|
|
|
|
has output => (is => 'rw'); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
has client => (is => 'lazy'); |
122
|
|
|
|
|
|
|
has ec2 => (is => 'lazy'); |
123
|
|
|
|
|
|
|
has node => (is => 'lazy'); |
124
|
|
|
|
|
|
|
has vault => (is => 'lazy'); |
125
|
|
|
|
|
|
|
has search => (is => 'lazy'); |
126
|
|
|
|
|
|
|
has data_bag => (is => 'lazy'); |
127
|
|
|
|
|
|
|
|
128
|
1
|
|
|
1
|
|
1653
|
sub _build_client { Chef::Knife::Cmd::Client->new(knife => shift) } |
129
|
1
|
|
|
1
|
|
1593
|
sub _build_ec2 { Chef::Knife::Cmd::EC2->new(knife => shift) } |
130
|
1
|
|
|
1
|
|
1671
|
sub _build_node { Chef::Knife::Cmd::Node->new(knife => shift) } |
131
|
1
|
|
|
1
|
|
1614
|
sub _build_vault { Chef::Knife::Cmd::Vault->new(knife => shift) } |
132
|
0
|
|
|
0
|
|
0
|
sub _build_search { Chef::Knife::Cmd::Search->new(knife => shift) } |
133
|
0
|
|
|
0
|
|
0
|
sub _build_data_bag { Chef::Knife::Cmd::DataBag->new(knife => shift) } |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub _build_shell { |
136
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
137
|
|
|
|
|
|
|
my $cb = sub { |
138
|
0
|
|
|
0
|
|
0
|
my ($type, $message) = @_; |
139
|
0
|
0
|
|
|
|
0
|
if ($type ne 'error') { |
140
|
0
|
0
|
|
|
|
0
|
if ($type eq 'command') { |
141
|
0
|
|
|
|
|
0
|
$self->output(''); |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
else { |
144
|
0
|
|
|
|
|
0
|
my $output = ''; |
145
|
0
|
0
|
|
|
|
0
|
$output .= $self->output . "\n" if $self->output; |
146
|
0
|
|
|
|
|
0
|
$output .= $message; |
147
|
0
|
|
|
|
|
0
|
$self->output($output); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
} |
150
|
0
|
0
|
|
|
|
0
|
$self->callback->(@_) if $self->callback; |
151
|
0
|
|
|
|
|
0
|
}; |
152
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
0
|
return Shell::Carapace->shell(callback => $cb); |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub bootstrap { |
157
|
1
|
|
|
1
|
|
1363
|
my ($self, $fqdn, %options) = @_; |
158
|
1
|
|
|
|
|
5
|
my @opts = $self->handle_options(%options); |
159
|
1
|
|
|
|
|
4
|
my @cmd = (qw/knife bootstrap/, $fqdn, @opts); |
160
|
1
|
|
|
|
|
3
|
$self->run(@cmd); |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub handle_options { |
164
|
17
|
|
|
17
|
0
|
4169
|
my ($self, %options) = @_; |
165
|
|
|
|
|
|
|
|
166
|
17
|
50
|
0
|
|
|
114
|
$options{format} //= $self->format if $self->format; |
167
|
|
|
|
|
|
|
|
168
|
17
|
50
|
33
|
|
|
64
|
$options{format} && $options{format} eq 'json' |
169
|
|
|
|
|
|
|
? $self->_json_flag(1) |
170
|
|
|
|
|
|
|
: $self->_json_flag(0); |
171
|
|
|
|
|
|
|
|
172
|
17
|
|
|
|
|
16
|
my @opts; |
173
|
17
|
|
|
|
|
47
|
for my $option (sort keys %options) { |
174
|
17
|
|
|
|
|
17
|
my $value = $options{$option}; |
175
|
17
|
|
|
|
|
26
|
$option =~ s/_/-/g; |
176
|
|
|
|
|
|
|
|
177
|
17
|
|
|
|
|
25
|
push @opts, "--$option"; |
178
|
17
|
100
|
|
|
|
39
|
push @opts, $value if $value ne "1"; |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
17
|
|
|
|
|
55
|
return @opts; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub run { |
185
|
17
|
|
|
17
|
0
|
2236
|
my ($self, @cmds) = @_; |
186
|
17
|
50
|
|
|
|
85
|
return shell_quote @cmds if $self->noop; |
187
|
0
|
|
|
|
|
|
$self->shell->run(@cmds); |
188
|
0
|
|
|
|
|
|
my $out = $self->output; |
189
|
0
|
0
|
|
|
|
|
return JSON->new->utf8->decode($out) if $self->_json_flag; |
190
|
0
|
|
|
|
|
|
return $out; |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
1; |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head1 SEE ALSO |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=over 4 |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=item L<Capture::Tiny::Extended> |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=item L<Capture::Tiny> |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item L<IPC::System::Simple> |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=back |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=head1 LICENSE |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
210
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=head1 AUTHOR |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
Eric Johnson E<lt>eric.git@iijo.orgE<gt> |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=cut |