Add config class.
authorRené Jochum <r.jochum@proxmox.com>
Mon, 4 Jun 2018 14:49:02 +0000 (16:49 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 5 Jun 2018 04:26:17 +0000 (06:26 +0200)
Signed-off-by: René Jochum <r.jochum@proxmox.com>
PVE/APIClient/Commands/lxc.pm
PVE/APIClient/Commands/remote.pm
PVE/APIClient/Config.pm

index d1fffb7..7403143 100644 (file)
@@ -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'});
index a6eb512..8cedf08 100644 (file)
@@ -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 $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,
 });
 
index e29a4fd..6c5b537 100644 (file)
@@ -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 $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;