]>
Commit | Line | Data |
---|---|---|
1 | package PVE::APIClient::Config; | |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use JSON; | |
6 | ||
7 | use PVE::JSONSchema qw(register_standard_option get_standard_option); | |
8 | use PVE::SectionConfig; | |
9 | use PVE::Tools qw(file_get_contents file_set_contents); | |
10 | ||
11 | use base qw(PVE::SectionConfig); | |
12 | ||
13 | my $complete_remote_name = sub { | |
14 | ||
15 | my $config = PVE::APIClient::Config->load(); | |
16 | return [keys %{$config->{ids}}]; | |
17 | }; | |
18 | ||
19 | register_standard_option('pveclient-remote-name', { | |
20 | description => "The name of the remote.", | |
21 | type => 'string', | |
22 | pattern => qr(\w+), | |
23 | completion => $complete_remote_name, | |
24 | }); | |
25 | ||
26 | ||
27 | my $defaultData = { | |
28 | propertyList => { | |
29 | type => { | |
30 | description => "Section type.", | |
31 | optional => 1, | |
32 | }, | |
33 | name => get_standard_option('pveclient-remote-name'), | |
34 | host => { | |
35 | description => "The host.", | |
36 | type => 'string', format => 'address', | |
37 | optional => 1, | |
38 | }, | |
39 | username => { | |
40 | description => "The username.", | |
41 | type => 'string', | |
42 | optional => 1, | |
43 | }, | |
44 | password => { | |
45 | description => "The users password.", | |
46 | type => 'string', | |
47 | optional => 1, | |
48 | }, | |
49 | port => { | |
50 | description => "The port.", | |
51 | type => 'integer', | |
52 | optional => 1, | |
53 | default => 8006, | |
54 | }, | |
55 | fingerprint => { | |
56 | description => "Fingerprint.", | |
57 | type => 'string', | |
58 | optional => 1, | |
59 | }, | |
60 | comment => { | |
61 | description => "Description.", | |
62 | type => 'string', | |
63 | optional => 1, | |
64 | maxLength => 4096, | |
65 | }, | |
66 | }, | |
67 | }; | |
68 | ||
69 | sub type { | |
70 | return 'remote'; | |
71 | } | |
72 | ||
73 | sub options { | |
74 | return { | |
75 | name => { optional => 0 }, | |
76 | host => { optional => 0 }, | |
77 | comment => { optional => 1 }, | |
78 | username => { optional => 0 }, | |
79 | password => { optional => 1 }, | |
80 | port => { optional => 1 }, | |
81 | fingerprint => { optional => 1 }, | |
82 | }; | |
83 | } | |
84 | ||
85 | sub private { | |
86 | return $defaultData; | |
87 | } | |
88 | ||
89 | sub config_filename { | |
90 | my ($class) = @_; | |
91 | ||
92 | my $home = $ENV{HOME}; | |
93 | ||
94 | die "environment HOME not set\n" if !defined($home); | |
95 | ||
96 | return "$home/.pveclient"; | |
97 | } | |
98 | ||
99 | sub load { | |
100 | my ($class) = @_; | |
101 | ||
102 | my $filename = $class->config_filename(); | |
103 | ||
104 | my $raw = ''; | |
105 | ||
106 | if (-e $filename) { | |
107 | my $filemode = (stat($filename))[2] & 07777; | |
108 | if ($filemode != 0600) { | |
109 | die sprintf "wrong permissions on '$filename' %04o (expected 0600)\n", $filemode; | |
110 | } | |
111 | ||
112 | $raw = file_get_contents($filename); | |
113 | } | |
114 | ||
115 | return $class->parse_config($filename, $raw); | |
116 | } | |
117 | ||
118 | sub save { | |
119 | my ($class, $cfg) = @_; | |
120 | ||
121 | my $filename = $class->config_filename(); | |
122 | my $raw = $class->write_config($filename, $cfg); | |
123 | ||
124 | file_set_contents($filename, $raw, 0600); | |
125 | } | |
126 | ||
127 | sub lookup_remote { | |
128 | my ($class, $cfg, $name, $noerr) = @_; | |
129 | ||
130 | my $data = $cfg->{ids}->{$name}; | |
131 | ||
132 | return $data if $noerr || defined($data); | |
133 | ||
134 | die "unknown remote \"$name\"\n"; | |
135 | } | |
136 | ||
137 | sub remote_conn { | |
138 | my ($class, $cfg, $remote) = @_; | |
139 | ||
140 | my $section = $class->lookup_remote($cfg, $remote); | |
141 | ||
142 | my $password = $section->{password}; | |
143 | if (!defined($password)) { | |
144 | $password = PVE::PTY::read_password("Remote password: ") | |
145 | } | |
146 | ||
147 | my $conn = PVE::APIClient::LWP->new( | |
148 | username => $section->{username}, | |
149 | password => $password, | |
150 | host => $section->{host}, | |
151 | port => $section->{port} // 8006, | |
152 | cached_fingerprints => { | |
153 | $section->{fingerprint} => 1, | |
154 | } | |
155 | ); | |
156 | ||
157 | $conn->login; | |
158 | ||
159 | return $conn; | |
160 | } | |
161 | ||
162 | __PACKAGE__->register(); | |
163 | __PACKAGE__->init(); | |
164 | ||
165 | 1; |