]>
Commit | Line | Data |
---|---|---|
565bbc73 DM |
1 | package PVE::APIClient::Commands::remote; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
b4007425 | 6 | use PVE::APIClient::Helpers; |
c9138c03 | 7 | use PVE::APIClient::JSONSchema qw(get_standard_option); |
ca3269f4 | 8 | use PVE::APIClient::Tools qw(extract_param); |
3454a319 DM |
9 | use PVE::APIClient::Config; |
10 | ||
c9138c03 | 11 | use PVE::APIClient::CLIHandler; |
565bbc73 | 12 | |
2d0ebe21 | 13 | use PVE::APIClient::LWP; |
c9138c03 | 14 | use PVE::APIClient::PTY; |
2d0ebe21 | 15 | |
c9138c03 | 16 | use base qw(PVE::APIClient::CLIHandler); |
565bbc73 | 17 | |
2d0ebe21 | 18 | sub read_password { |
b2123baa | 19 | return PVE::APIClient::PTY::read_password("Remote password: ") |
2d0ebe21 RJ |
20 | } |
21 | ||
5101e472 DM |
22 | # define as array to keep ordering |
23 | my $remote_list_returns_properties = [ | |
24 | name => get_standard_option('pveclient-remote-name'), | |
25 | host => { type => 'string', format => 'address' }, | |
26 | username => { type => 'string' }, | |
27 | port => { type => 'integer', optional => 1 }, | |
28 | fingerprint => { type => 'string', optional => 1 }, | |
29 | ]; | |
30 | ||
e2ca543c | 31 | __PACKAGE__->register_method ({ |
e3468666 DM |
32 | name => 'remote_list', |
33 | path => 'remote_list', | |
e2ca543c RJ |
34 | method => 'GET', |
35 | description => "List remotes from your config file.", | |
36 | parameters => { | |
37 | additionalProperties => 0, | |
59d3653b | 38 | properties => {}, |
5101e472 DM |
39 | }, |
40 | returns => { | |
41 | type => 'array', | |
42 | items => { | |
43 | type => 'object', | |
44 | properties => { @$remote_list_returns_properties }, | |
45 | }, | |
e2ca543c | 46 | }, |
e2ca543c | 47 | code => sub { |
5101e472 DM |
48 | my ($param) = @_; |
49 | ||
69aa81b3 | 50 | my $config = PVE::APIClient::Config->load(); |
e2ca543c | 51 | |
5101e472 | 52 | my $res = []; |
69aa81b3 | 53 | for my $name (keys %{$config->{ids}}) { |
a6dab5b8 DM |
54 | my $data = $config->{ids}->{$name}; |
55 | next if $data->{type} ne 'remote'; | |
5101e472 | 56 | push @$res, $data; |
e2ca543c RJ |
57 | } |
58 | ||
5101e472 | 59 | return $res; |
e2ca543c RJ |
60 | }}); |
61 | ||
565bbc73 | 62 | __PACKAGE__->register_method ({ |
e3468666 DM |
63 | name => 'remote_add', |
64 | path => 'remote_add', | |
565bbc73 DM |
65 | method => 'POST', |
66 | description => "Add a remote to your config file.", | |
a6dab5b8 | 67 | parameters => PVE::APIClient::RemoteConfig->createSchema(1), |
565bbc73 DM |
68 | returns => { type => 'null'}, |
69 | code => sub { | |
70 | my ($param) = @_; | |
71 | ||
69aa81b3 DM |
72 | my $remote = $param->{name}; |
73 | ||
b4007425 | 74 | # Note: we try to keep lock time sort, and lock later when we have all info |
69aa81b3 DM |
75 | my $config = PVE::APIClient::Config->load(); |
76 | ||
77 | die "Remote '$remote' already exists\n" | |
78 | if $config->{ids}->{$remote}; | |
2d0ebe21 RJ |
79 | |
80 | my $last_fp = 0; | |
69aa81b3 | 81 | |
8842464b DM |
82 | my $password = $param->{password}; |
83 | if (!defined($password)) { | |
b2123baa | 84 | $password = PVE::APIClient::PTY::read_password("Remote password: "); |
8842464b DM |
85 | } |
86 | ||
69aa81b3 | 87 | my $setup = { |
2d0ebe21 | 88 | username => $param->{username}, |
8842464b | 89 | password => $password, |
2d0ebe21 RJ |
90 | host => $param->{host}, |
91 | port => $param->{port} // 8006, | |
69aa81b3 DM |
92 | }; |
93 | ||
94 | if ($param->{fingerprint}) { | |
95 | $setup->{cached_fingerprints} = { | |
96 | $param->{fingerprint} => 1, | |
97 | }; | |
98 | } else { | |
99 | $setup->{manual_verification} = 1; | |
100 | $setup->{register_fingerprint_cb} = sub { | |
101 | my $fp = shift @_; | |
102 | $last_fp = $fp; | |
103 | }; | |
104 | } | |
105 | ||
a304c3d7 | 106 | my $api = PVE::APIClient::LWP->new(%$setup); |
2d0ebe21 RJ |
107 | $api->login(); |
108 | ||
69aa81b3 | 109 | $param->{fingerprint} = $last_fp if !defined($param->{fingerprint}); |
b4007425 | 110 | |
69aa81b3 | 111 | my $plugin = PVE::APIClient::Config->lookup('remote'); |
69aa81b3 | 112 | |
b4007425 DM |
113 | my $code = sub { |
114 | ||
115 | $config = PVE::APIClient::Config->load(); # reload | |
116 | ||
117 | # check again (file is locked now) | |
118 | die "Remote '$remote' already exists\n" | |
119 | if $config->{ids}->{$remote}; | |
120 | ||
121 | my $opts = $plugin->check_config($remote, $param, 1, 1); | |
122 | ||
123 | $config->{ids}->{$remote} = $opts; | |
124 | ||
125 | PVE::APIClient::Config->save($config); | |
126 | }; | |
127 | ||
128 | PVE::APIClient::Config->lock_config(undef, $code); | |
69aa81b3 DM |
129 | |
130 | return undef; | |
131 | }}); | |
132 | ||
133 | __PACKAGE__->register_method ({ | |
e3468666 DM |
134 | name => 'remote_set', |
135 | path => 'remote_set', | |
69aa81b3 DM |
136 | method => 'PUT', |
137 | description => "Update a remote configuration.", | |
a6dab5b8 | 138 | parameters => PVE::APIClient::RemoteConfig->updateSchema(1), |
69aa81b3 DM |
139 | returns => { type => 'null'}, |
140 | code => sub { | |
141 | my ($param) = @_; | |
142 | ||
69aa81b3 DM |
143 | my $name = extract_param($param, 'name'); |
144 | my $digest = extract_param($param, 'digest'); | |
145 | my $delete = extract_param($param, 'delete'); | |
146 | ||
b4007425 DM |
147 | my $code = sub { |
148 | my $config = PVE::APIClient::Config->load(); | |
149 | my $remote = PVE::APIClient::Config->lookup_remote($config, $name); | |
69aa81b3 | 150 | |
b4007425 DM |
151 | my $plugin = PVE::APIClient::Config->lookup('remote'); |
152 | my $opts = $plugin->check_config($name, $param, 0, 1); | |
69aa81b3 | 153 | |
b4007425 DM |
154 | foreach my $k (%$opts) { |
155 | $remote->{$k} = $opts->{$k}; | |
156 | } | |
69aa81b3 | 157 | |
b4007425 DM |
158 | if ($delete) { |
159 | my $options = $plugin->private()->{options}->{'remote'}; | |
160 | foreach my $k (PVE::APIClient::Tools::APIClient::split_list($delete)) { | |
161 | my $d = $options->{$k} || | |
162 | die "no such option '$k'\n"; | |
163 | die "unable to delete required option '$k'\n" | |
164 | if !$d->{optional}; | |
165 | die "unable to delete fixed option '$k'\n" | |
166 | if $d->{fixed}; | |
167 | delete $remote->{$k}; | |
168 | } | |
69aa81b3 | 169 | } |
69aa81b3 | 170 | |
b4007425 DM |
171 | PVE::APIClient::Config->save($config); |
172 | }; | |
173 | ||
174 | PVE::APIClient::Config->lock_config(undef, $code); | |
565bbc73 | 175 | |
2d0ebe21 | 176 | return undef; |
565bbc73 DM |
177 | }}); |
178 | ||
179 | __PACKAGE__->register_method ({ | |
e3468666 DM |
180 | name => 'remote_delete', |
181 | path => 'remote_delete', | |
565bbc73 DM |
182 | method => 'DELETE', |
183 | description => "Removes a remote from your config file.", | |
184 | parameters => { | |
185 | additionalProperties => 0, | |
186 | properties => { | |
3454a319 | 187 | name => get_standard_option('pveclient-remote-name'), |
565bbc73 DM |
188 | }, |
189 | }, | |
190 | returns => { type => 'null'}, | |
191 | code => sub { | |
192 | my ($param) = @_; | |
193 | ||
b4007425 DM |
194 | my $code = sub { |
195 | my $config = PVE::APIClient::Config->load(); | |
196 | delete $config->{ids}->{$param->{name}}; | |
197 | PVE::APIClient::Config->save($config); | |
198 | }; | |
69aa81b3 | 199 | |
b4007425 | 200 | PVE::APIClient::Config->lock_config(undef, $code); |
565bbc73 | 201 | |
f79acf69 | 202 | return undef; |
565bbc73 DM |
203 | }}); |
204 | ||
205 | our $cmddef = { | |
e3468666 DM |
206 | add => [ __PACKAGE__, 'remote_add', ['name', 'host', 'username']], |
207 | set => [ __PACKAGE__, 'remote_set', ['name']], | |
208 | delete => [ __PACKAGE__, 'remote_delete', ['name']], | |
4aba8d31 DM |
209 | list => [__PACKAGE__, 'remote_list', undef, {}, |
210 | sub { | |
211 | my ($data, $schema, $options) = @_; | |
212 | PVE::APIClient::Helpers::print_ordered_result($remote_list_returns_properties, $data, $schema, $options); | |
213 | }, | |
214 | $PVE::APIClient::RESTHandler::standard_output_options, | |
215 | ], | |
565bbc73 DM |
216 | }; |
217 | ||
218 | 1; |