mirror of
https://git.proxmox.com/git/pve-client
synced 2025-10-04 20:37:13 +00:00
Add config class.
Signed-off-by: René Jochum <r.jochum@proxmox.com>
This commit is contained in:
parent
63c02d8ce7
commit
06039c7f9b
@ -147,7 +147,7 @@ __PACKAGE__->register_method ({
|
||||
code => sub {
|
||||
my ($param) = @_;
|
||||
|
||||
my $conn = PVE::APIClient::Config::get_remote_connection($param->{remote});
|
||||
my $conn = PVE::APIClient::Config->new()->remote_conn($param->{remote});
|
||||
|
||||
# Get the real node from the resources endpoint
|
||||
my $resource_list = $conn->get("api2/json/cluster/resources", { type => 'vm'});
|
||||
|
@ -10,27 +10,18 @@ use PVE::CLIHandler;
|
||||
|
||||
use base qw(PVE::CLIHandler);
|
||||
|
||||
my $remote_name_regex = qr(\w+);
|
||||
|
||||
my $complete_remote_name = sub {
|
||||
|
||||
my $conf = PVE::APIClient::Config::load_config();
|
||||
my $config = PVE::APIClient::Config->new();
|
||||
my $known_remotes = $config->remotes;
|
||||
|
||||
my $res = [];
|
||||
|
||||
foreach my $k (keys %$conf) {
|
||||
if ($k =~ m/^remote_($remote_name_regex)$/) {
|
||||
push @$res, $1;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
return [keys %{$known_remotes}];
|
||||
};
|
||||
|
||||
register_standard_option('pveclient-remote-name', {
|
||||
description => "The name of the remote.",
|
||||
type => 'string',
|
||||
pattern => $remote_name_regex,
|
||||
pattern => qr([\w\d\.\-\_]+),
|
||||
completion => $complete_remote_name,
|
||||
});
|
||||
|
||||
|
@ -3,51 +3,135 @@ package PVE::APIClient::Config;
|
||||
use strict;
|
||||
use warnings;
|
||||
use JSON;
|
||||
use File::HomeDir;
|
||||
|
||||
use PVE::Tools;
|
||||
use PVE::APIClient::LWP;
|
||||
use File::HomeDir ();
|
||||
use PVE::Tools qw(file_get_contents file_set_contents);
|
||||
|
||||
sub load_config {
|
||||
sub new {
|
||||
my ($class) = @_;
|
||||
|
||||
my $filename = home() . '/.pveclient';
|
||||
my $conf_str = PVE::Tools::file_get_contents($filename);
|
||||
my $self = {
|
||||
file => File::HomeDir::home() . '/.pveclient',
|
||||
};
|
||||
bless $self => $class;
|
||||
|
||||
my $filemode = (stat($filename))[2] & 07777;
|
||||
if ($filemode != 0600) {
|
||||
die sprintf "wrong permissions on '$filename' %04o (expected 0600)\n", $filemode;
|
||||
}
|
||||
$self->load();
|
||||
|
||||
return decode_json($conf_str);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub load_remote_config {
|
||||
my ($remote) = @_;
|
||||
sub load {
|
||||
my ($self) = @_;
|
||||
|
||||
my $conf = load_config();
|
||||
if (-e $self->{file}) {
|
||||
my $filemode = (stat($self->{file}))[2] & 07777;
|
||||
if ($filemode != 0600) {
|
||||
die sprintf "wrong permissions on '$self->{file}' %04o (expected 0600)\n", $filemode;
|
||||
}
|
||||
|
||||
my $remote_conf = $conf->{"remote_$remote"} ||
|
||||
die "no such remote '$remote'\n";
|
||||
|
||||
foreach my $opt (qw(hostname username password fingerprint)) {
|
||||
die "missing option '$opt' (remote '$remote')" if !defined($remote_conf->{$opt});
|
||||
my $contents = file_get_contents($self->{file});
|
||||
$self->{data} = from_json($contents);
|
||||
} else {
|
||||
$self->{data} = {};
|
||||
}
|
||||
|
||||
return $remote_conf;
|
||||
if (!exists($self->{data}->{remotes})) {
|
||||
$self->{data}->{remotes} = {};
|
||||
}
|
||||
|
||||
# Verify config
|
||||
for my $name (@{$self->remote_names}) {
|
||||
my $cfg = $self->{data}->{remotes}->{$name};
|
||||
|
||||
foreach my $opt (qw(host port username fingerprint)) {
|
||||
die "missing option '$opt' (remote '$name')" if !defined($cfg->{$opt});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_remote_connection {
|
||||
my ($remote) = @_;
|
||||
sub save {
|
||||
my ($self) = @_;
|
||||
|
||||
my $conf = load_remote_config($remote);
|
||||
my $contents = to_json($self->{data}, {pretty => 1, canonical => 1});
|
||||
file_set_contents($self->{file}, $contents, 0600);
|
||||
}
|
||||
|
||||
return PVE::APIClient::LWP->new(
|
||||
username => $conf->{username},
|
||||
password => $conf->{password},
|
||||
host => $conf->{hostname},
|
||||
cached_fingerprints => {
|
||||
$conf->{fingerprint} => 1
|
||||
});
|
||||
sub add_remote {
|
||||
my ($self, $name, $host, $port, $fingerprint, $username, $password) = @_;
|
||||
|
||||
$self->{data}->{remotes}->{$name} = {
|
||||
host => $host,
|
||||
port => $port,
|
||||
fingerprint => $fingerprint,
|
||||
username => $username,
|
||||
};
|
||||
|
||||
if (defined($password)) {
|
||||
$self->{data}->{remotes}->{$name}->{password} = $password;
|
||||
}
|
||||
}
|
||||
|
||||
sub remote_names {
|
||||
my ($self) = @_;
|
||||
|
||||
return [keys %{$self->{data}->{remotes}}];
|
||||
}
|
||||
|
||||
sub lookup_remote {
|
||||
my ($self, $name) = @_;
|
||||
|
||||
die "Unknown remote \"$name\" given"
|
||||
if (!exists($self->{data}->{remotes}->{$name}));
|
||||
|
||||
return $self->{data}->{remotes}->{$name};
|
||||
}
|
||||
|
||||
sub remotes {
|
||||
my ($self) = @_;
|
||||
|
||||
my $res = {};
|
||||
|
||||
# Remove the password from each remote.
|
||||
for my $name ($self->remote_names) {
|
||||
my $cfg = $self->{data}->{remotes}->{$name};
|
||||
$res->{$name} = {
|
||||
host => $cfg->{host},
|
||||
port => $cfg->{port},
|
||||
username => $cfg->{username},
|
||||
fingerprint => $cfg->{fingerprint},
|
||||
};
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub remove_remote {
|
||||
my ($self, $remote) = @_;
|
||||
|
||||
$self->lookup_remote($remote);
|
||||
|
||||
delete($self->{data}->{remotes}->{$remote});
|
||||
|
||||
$self->save();
|
||||
}
|
||||
|
||||
sub remote_conn {
|
||||
my ($self, $remote) = @_;
|
||||
|
||||
my $section = $self->lookup_remote($remote);
|
||||
my $conn = PVE::APIClient::LWP->new(
|
||||
username => $section->{username},
|
||||
password => $section->{password},
|
||||
host => $section->{host},
|
||||
port => $section->{port},
|
||||
cached_fingerprints => {
|
||||
$section->{fingerprint} => 1,
|
||||
}
|
||||
);
|
||||
|
||||
$conn->login;
|
||||
|
||||
return $conn;
|
||||
}
|
||||
|
||||
1;
|
||||
|
Loading…
Reference in New Issue
Block a user