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