]> git.proxmox.com Git - pve-client.git/blob - PVE/APIClient/Config.pm
register stanadard option 'pveclient-output-format'
[pve-client.git] / PVE / APIClient / Config.pm
1 package PVE::APIClient::Config;
2
3 use strict;
4 use warnings;
5 use JSON;
6
7 use PVE::APIClient::JSONSchema;
8 use PVE::APIClient::SectionConfig;
9 use PVE::APIClient::Tools qw(file_get_contents file_set_contents);
10
11 use base qw(PVE::APIClient::SectionConfig);
12
13 my $remote_namne_regex = qw(\w+);
14
15 my $defaults_section = '!DEFAULTS';
16
17 my $complete_remote_name = sub {
18
19 my $config = PVE::APIClient::Config->load();
20 my $list = [];
21 foreach my $name (keys %{$config->{ids}}) {
22 push @$list, $name if $name ne $defaults_section;
23 }
24 return $list;
25 };
26
27 PVE::APIClient::JSONSchema::register_standard_option('pveclient-output-format', {
28 type => 'string',
29 description => 'Output format.',
30 enum => [ 'table', 'json' ],
31 optional => 1,
32 default => 'table',
33 });
34
35 PVE::APIClient::JSONSchema::register_standard_option('pveclient-remote-name', {
36 description => "The name of the remote.",
37 type => 'string',
38 pattern => $remote_namne_regex,
39 completion => $complete_remote_name,
40 });
41
42 my $defaultData = {
43 propertyList => {
44 type => {
45 description => "Section type.",
46 optional => 1,
47 },
48 },
49 };
50
51 sub private {
52 return $defaultData;
53 }
54
55 sub config_filename {
56 my ($class) = @_;
57
58 my $home = $ENV{HOME};
59
60 die "environment HOME not set\n" if !defined($home);
61
62 return "$home/.pveclient";
63 }
64
65 sub format_section_header {
66 my ($class, $type, $sectionId, $scfg, $done_hash) = @_;
67
68 if ($type eq 'defaults') {
69 return "defaults:\n";
70 } else {
71 return "$type: $sectionId\n";
72 }
73 }
74
75 sub parse_section_header {
76 my ($class, $line) = @_;
77
78 if ($line =~ m/^defaults:\s*$/) {
79 return ('defaults', $defaults_section, undef, {});
80 } elsif ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
81 my ($type, $name) = (lc($1), $2);
82 eval {
83 die "invalid remote name '$name'\n"
84 if $name eq $defaults_section || $name !~ m/^$remote_namne_regex$/;
85 };
86 return ($type, $name, $@, {});
87 }
88 return undef;
89 }
90
91 sub load {
92 my ($class) = @_;
93
94 my $filename = $class->config_filename();
95
96 my $raw = '';
97
98 if (-e $filename) {
99 my $filemode = (stat($filename))[2] & 07777;
100 if ($filemode != 0600) {
101 die sprintf "wrong permissions on '$filename' %04o (expected 0600)\n", $filemode;
102 }
103
104 $raw = file_get_contents($filename);
105 }
106
107 return $class->parse_config($filename, $raw);
108 }
109
110 sub save {
111 my ($class, $cfg) = @_;
112
113 my $filename = $class->config_filename();
114
115 $cfg->{order}->{$defaults_section} = -1; # write as first section
116 my $raw = $class->write_config($filename, $cfg);
117
118 file_set_contents($filename, $raw, 0600);
119 }
120
121 sub get_defaults {
122 my ($class, $cfg) = @_;
123
124 $cfg->{ids}->{$defaults_section} //= {};
125
126 return $cfg->{ids}->{$defaults_section};
127 }
128
129 sub lookup_remote {
130 my ($class, $cfg, $name, $noerr) = @_;
131
132 my $data = $cfg->{ids}->{$name};
133
134 return $data if $noerr || defined($data);
135
136 die "unknown remote \"$name\"\n";
137 }
138
139 sub remote_conn {
140 my ($class, $cfg, $remote) = @_;
141
142 my $section = $class->lookup_remote($cfg, $remote);
143
144 my $password = $section->{password};
145 if (!defined($password)) {
146 $password = PVE::PTY::read_password("Remote password: ")
147 }
148
149 my $conn = PVE::APIClient::LWP->new(
150 username => $section->{username},
151 password => $password,
152 host => $section->{host},
153 port => $section->{port} // 8006,
154 cached_fingerprints => {
155 $section->{fingerprint} => 1,
156 }
157 );
158
159 $conn->login;
160
161 return $conn;
162 }
163
164 package PVE::APIClient::RemoteConfig;
165
166 use strict;
167 use warnings;
168
169 use PVE::APIClient::JSONSchema qw(register_standard_option get_standard_option);
170 use PVE::APIClient::SectionConfig;
171
172 use base qw( PVE::APIClient::Config);
173
174 sub type {
175 return 'remote';
176 }
177
178 sub properties {
179 return {
180 name => get_standard_option('pveclient-remote-name'),
181 host => {
182 description => "The host.",
183 type => 'string', format => 'address',
184 optional => 1,
185 },
186 username => {
187 description => "The username.",
188 type => 'string',
189 optional => 1,
190 },
191 password => {
192 description => "The users password.",
193 type => 'string',
194 optional => 1,
195 },
196 port => {
197 description => "The port.",
198 type => 'integer',
199 optional => 1,
200 default => 8006,
201 },
202 fingerprint => {
203 description => "Fingerprint.",
204 type => 'string',
205 optional => 1,
206 },
207 comment => {
208 description => "Description.",
209 type => 'string',
210 optional => 1,
211 maxLength => 4096,
212 },
213 };
214 }
215
216 sub options {
217 return {
218 name => { optional => 0 },
219 host => { optional => 0 },
220 comment => { optional => 1 },
221 username => { optional => 0 },
222 password => { optional => 1 },
223 port => { optional => 1 },
224 fingerprint => { optional => 1 },
225 };
226 }
227
228 __PACKAGE__->register();
229
230
231 package PVE::APIClient::DefaultsConfig;
232
233 use strict;
234 use warnings;
235
236 use PVE::APIClient::JSONSchema qw(register_standard_option get_standard_option);
237
238 use base qw( PVE::APIClient::Config);
239
240
241 sub type {
242 return 'defaults';
243 }
244
245 sub options {
246 return {
247 name => { optional => 1 },
248 username => { optional => 1 },
249 port => { optional => 1 },
250 };
251 }
252
253 __PACKAGE__->register();
254
255
256 PVE::APIClient::Config->init();
257
258 1;