mirror of
https://git.proxmox.com/git/pve-client
synced 2025-10-04 15:33:28 +00:00
251 lines
4.9 KiB
Perl
251 lines
4.9 KiB
Perl
package PVE::APIClient::Config;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use JSON;
|
|
|
|
use PVE::APIClient::JSONSchema;
|
|
use PVE::APIClient::SectionConfig;
|
|
use PVE::APIClient::Tools qw(file_get_contents file_set_contents);
|
|
|
|
use base qw(PVE::APIClient::SectionConfig);
|
|
|
|
my $remote_namne_regex = qw(\w+);
|
|
|
|
my $defaults_section = '!DEFAULTS';
|
|
|
|
my $complete_remote_name = sub {
|
|
|
|
my $config = PVE::APIClient::Config->load();
|
|
my $list = [];
|
|
foreach my $name (keys %{$config->{ids}}) {
|
|
push @$list, $name if $name ne $defaults_section;
|
|
}
|
|
return $list;
|
|
};
|
|
|
|
PVE::APIClient::JSONSchema::register_standard_option('pveclient-remote-name', {
|
|
description => "The name of the remote.",
|
|
type => 'string',
|
|
pattern => $remote_namne_regex,
|
|
completion => $complete_remote_name,
|
|
});
|
|
|
|
my $defaultData = {
|
|
propertyList => {
|
|
type => {
|
|
description => "Section type.",
|
|
optional => 1,
|
|
},
|
|
},
|
|
};
|
|
|
|
sub private {
|
|
return $defaultData;
|
|
}
|
|
|
|
sub config_filename {
|
|
my ($class) = @_;
|
|
|
|
my $home = $ENV{HOME};
|
|
|
|
die "environment HOME not set\n" if !defined($home);
|
|
|
|
return "$home/.pveclient";
|
|
}
|
|
|
|
sub format_section_header {
|
|
my ($class, $type, $sectionId, $scfg, $done_hash) = @_;
|
|
|
|
if ($type eq 'defaults') {
|
|
return "defaults:\n";
|
|
} else {
|
|
return "$type: $sectionId\n";
|
|
}
|
|
}
|
|
|
|
sub parse_section_header {
|
|
my ($class, $line) = @_;
|
|
|
|
if ($line =~ m/^defaults:\s*$/) {
|
|
return ('defaults', $defaults_section, undef, {});
|
|
} elsif ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
|
|
my ($type, $name) = (lc($1), $2);
|
|
eval {
|
|
die "invalid remote name '$name'\n"
|
|
if $name eq $defaults_section || $name !~ m/^$remote_namne_regex$/;
|
|
};
|
|
return ($type, $name, $@, {});
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub load {
|
|
my ($class) = @_;
|
|
|
|
my $filename = $class->config_filename();
|
|
|
|
my $raw = '';
|
|
|
|
if (-e $filename) {
|
|
my $filemode = (stat($filename))[2] & 07777;
|
|
if ($filemode != 0600) {
|
|
die sprintf "wrong permissions on '$filename' %04o (expected 0600)\n", $filemode;
|
|
}
|
|
|
|
$raw = file_get_contents($filename);
|
|
}
|
|
|
|
return $class->parse_config($filename, $raw);
|
|
}
|
|
|
|
sub save {
|
|
my ($class, $cfg) = @_;
|
|
|
|
my $filename = $class->config_filename();
|
|
|
|
$cfg->{order}->{$defaults_section} = -1; # write as first section
|
|
my $raw = $class->write_config($filename, $cfg);
|
|
|
|
file_set_contents($filename, $raw, 0600);
|
|
}
|
|
|
|
sub get_defaults {
|
|
my ($class, $cfg) = @_;
|
|
|
|
$cfg->{ids}->{$defaults_section} //= {};
|
|
|
|
return $cfg->{ids}->{$defaults_section};
|
|
}
|
|
|
|
sub lookup_remote {
|
|
my ($class, $cfg, $name, $noerr) = @_;
|
|
|
|
my $data = $cfg->{ids}->{$name};
|
|
|
|
return $data if $noerr || defined($data);
|
|
|
|
die "unknown remote \"$name\"\n";
|
|
}
|
|
|
|
sub remote_conn {
|
|
my ($class, $cfg, $remote) = @_;
|
|
|
|
my $section = $class->lookup_remote($cfg, $remote);
|
|
|
|
my $password = $section->{password};
|
|
if (!defined($password)) {
|
|
$password = PVE::PTY::read_password("Remote password: ")
|
|
}
|
|
|
|
my $conn = PVE::APIClient::LWP->new(
|
|
username => $section->{username},
|
|
password => $password,
|
|
host => $section->{host},
|
|
port => $section->{port} // 8006,
|
|
cached_fingerprints => {
|
|
$section->{fingerprint} => 1,
|
|
}
|
|
);
|
|
|
|
$conn->login;
|
|
|
|
return $conn;
|
|
}
|
|
|
|
package PVE::APIClient::RemoteConfig;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use PVE::APIClient::JSONSchema qw(register_standard_option get_standard_option);
|
|
use PVE::APIClient::SectionConfig;
|
|
|
|
use base qw( PVE::APIClient::Config);
|
|
|
|
sub type {
|
|
return 'remote';
|
|
}
|
|
|
|
sub properties {
|
|
return {
|
|
name => get_standard_option('pveclient-remote-name'),
|
|
host => {
|
|
description => "The host.",
|
|
type => 'string', format => 'address',
|
|
optional => 1,
|
|
},
|
|
username => {
|
|
description => "The username.",
|
|
type => 'string',
|
|
optional => 1,
|
|
},
|
|
password => {
|
|
description => "The users password.",
|
|
type => 'string',
|
|
optional => 1,
|
|
},
|
|
port => {
|
|
description => "The port.",
|
|
type => 'integer',
|
|
optional => 1,
|
|
default => 8006,
|
|
},
|
|
fingerprint => {
|
|
description => "Fingerprint.",
|
|
type => 'string',
|
|
optional => 1,
|
|
},
|
|
comment => {
|
|
description => "Description.",
|
|
type => 'string',
|
|
optional => 1,
|
|
maxLength => 4096,
|
|
},
|
|
};
|
|
}
|
|
|
|
sub options {
|
|
return {
|
|
name => { optional => 0 },
|
|
host => { optional => 0 },
|
|
comment => { optional => 1 },
|
|
username => { optional => 0 },
|
|
password => { optional => 1 },
|
|
port => { optional => 1 },
|
|
fingerprint => { optional => 1 },
|
|
};
|
|
}
|
|
|
|
__PACKAGE__->register();
|
|
|
|
|
|
package PVE::APIClient::DefaultsConfig;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use PVE::APIClient::JSONSchema qw(register_standard_option get_standard_option);
|
|
|
|
use base qw( PVE::APIClient::Config);
|
|
|
|
|
|
sub type {
|
|
return 'defaults';
|
|
}
|
|
|
|
sub options {
|
|
return {
|
|
name => { optional => 1 },
|
|
username => { optional => 1 },
|
|
port => { optional => 1 },
|
|
};
|
|
}
|
|
|
|
__PACKAGE__->register();
|
|
|
|
|
|
PVE::APIClient::Config->init();
|
|
|
|
1;
|