]> git.proxmox.com Git - pve-client.git/blob - PVE/APIClient/Config.pm
allow to setup remotes without password
[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::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;