From: René Jochum Date: Mon, 4 Jun 2018 14:49:02 +0000 (+0200) Subject: Add config class. X-Git-Url: https://git.proxmox.com/?p=pve-client.git;a=commitdiff_plain;h=06039c7f9bb20ba7259cdf5dbc4f6fff5fd05efc Add config class. Signed-off-by: René Jochum --- diff --git a/PVE/APIClient/Commands/lxc.pm b/PVE/APIClient/Commands/lxc.pm index d1fffb7..7403143 100644 --- a/PVE/APIClient/Commands/lxc.pm +++ b/PVE/APIClient/Commands/lxc.pm @@ -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'}); diff --git a/PVE/APIClient/Commands/remote.pm b/PVE/APIClient/Commands/remote.pm index a6eb512..8cedf08 100644 --- a/PVE/APIClient/Commands/remote.pm +++ b/PVE/APIClient/Commands/remote.pm @@ -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, }); diff --git a/PVE/APIClient/Config.pm b/PVE/APIClient/Config.pm index e29a4fd..6c5b537 100644 --- a/PVE/APIClient/Config.pm +++ b/PVE/APIClient/Config.pm @@ -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;