use base qw(PVE::CLIHandler);
-my $remote_name_regex = qr(\w+);
-
my $complete_remote_name = sub {
- my $conf = PVE::APIClient::Config::load_config();
-
- my $res = [];
-
- foreach my $k (keys %$conf) {
- if ($k =~ m/^remote_($remote_name_regex)$/) {
- push @$res, $1;
- }
- }
+ my $config = PVE::APIClient::Config->new();
+ my $known_remotes = $config->remotes;
- 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,
});
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 $self;
+}
+
+sub load {
+ my ($self) = @_;
+
+ 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 $contents = file_get_contents($self->{file});
+ $self->{data} = from_json($contents);
+ } else {
+ $self->{data} = {};
+ }
+
+ if (!exists($self->{data}->{remotes})) {
+ $self->{data}->{remotes} = {};
}
- return decode_json($conf_str);
+ # 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 load_remote_config {
- my ($remote) = @_;
+sub save {
+ my ($self) = @_;
+
+ my $contents = to_json($self->{data}, {pretty => 1, canonical => 1});
+ file_set_contents($self->{file}, $contents, 0600);
+}
- my $conf = load_config();
+sub add_remote {
+ my ($self, $name, $host, $port, $fingerprint, $username, $password) = @_;
- my $remote_conf = $conf->{"remote_$remote"} ||
- die "no such remote '$remote'\n";
+ $self->{data}->{remotes}->{$name} = {
+ host => $host,
+ port => $port,
+ fingerprint => $fingerprint,
+ username => $username,
+ };
- foreach my $opt (qw(hostname username password fingerprint)) {
- die "missing option '$opt' (remote '$remote')" if !defined($remote_conf->{$opt});
+ if (defined($password)) {
+ $self->{data}->{remotes}->{$name}->{password} = $password;
}
+}
- return $remote_conf;
+sub remote_names {
+ my ($self) = @_;
+
+ return [keys %{$self->{data}->{remotes}}];
}
-sub get_remote_connection {
- my ($remote) = @_;
+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,
+ }
+ );
- my $conf = load_remote_config($remote);
+ $conn->login;
- return PVE::APIClient::LWP->new(
- username => $conf->{username},
- password => $conf->{password},
- host => $conf->{hostname},
- cached_fingerprints => {
- $conf->{fingerprint} => 1
- });
+ return $conn;
}
1;