From a6dab5b8ed9239968d8096a727257183f5fc05a7 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Tue, 12 Jun 2018 06:21:56 +0200 Subject: [PATCH] Config.pm: add new defaults sections And implement a new command to setup defaults. --- PVE/APIClient/Commands/help.pm | 2 + PVE/APIClient/Commands/remote.pm | 11 +- PVE/APIClient/Config.pm | 195 ++++++++++++++++++++++--------- pveclient | 2 + 4 files changed, 150 insertions(+), 60 deletions(-) diff --git a/PVE/APIClient/Commands/help.pm b/PVE/APIClient/Commands/help.pm index 81d4d4a..efb964a 100644 --- a/PVE/APIClient/Commands/help.pm +++ b/PVE/APIClient/Commands/help.pm @@ -6,6 +6,7 @@ use warnings; use PVE::APIClient::Commands::help; use PVE::APIClient::Commands::list; use PVE::APIClient::Commands::lxc; +use PVE::APIClient::Commands::config; use PVE::APIClient::Commands::remote; use PVE::CLIHandler; @@ -59,6 +60,7 @@ __PACKAGE__->register_method ({ $assemble_usage_string->('list', $PVE::APIClient::Commands::list::cmddef); $assemble_usage_string->('lxc', $PVE::APIClient::Commands::lxc::cmddef); $assemble_usage_string->('remote', $PVE::APIClient::Commands::remote::cmddef); + $assemble_usage_string->('config', $PVE::APIClient::Commands::config::cmddef); $text .= "pveclient {options}\n\n"; diff --git a/PVE/APIClient/Commands/remote.pm b/PVE/APIClient/Commands/remote.pm index 781fb63..0f465ea 100644 --- a/PVE/APIClient/Commands/remote.pm +++ b/PVE/APIClient/Commands/remote.pm @@ -32,9 +32,10 @@ __PACKAGE__->register_method ({ printf("%10s %10s %10s %10s %100s\n", "Name", "Host", "Port", "Username", "Fingerprint"); for my $name (keys %{$config->{ids}}) { - my $remote = $config->{ids}->{$name}; - printf("%10s %10s %10s %10s %100s\n", $name, $remote->{'host'}, - $remote->{'port'} // '-', $remote->{'username'}, $remote->{'fingerprint'} // '-'); + my $data = $config->{ids}->{$name}; + next if $data->{type} ne 'remote'; + printf("%10s %10s %10s %10s %100s\n", $name, $data->{'host'}, + $data->{'port'} // '-', $data->{'username'}, $data->{'fingerprint'} // '-'); } return undef; @@ -45,7 +46,7 @@ __PACKAGE__->register_method ({ path => 'add', method => 'POST', description => "Add a remote to your config file.", - parameters => PVE::APIClient::Config->createSchema(1), + parameters => PVE::APIClient::RemoteConfig->createSchema(1), returns => { type => 'null'}, code => sub { my ($param) = @_; @@ -103,7 +104,7 @@ __PACKAGE__->register_method ({ path => 'update', method => 'PUT', description => "Update a remote configuration.", - parameters => PVE::APIClient::Config->updateSchema(1), + parameters => PVE::APIClient::RemoteConfig->updateSchema(1), returns => { type => 'null'}, code => sub { my ($param) = @_; diff --git a/PVE/APIClient/Config.pm b/PVE/APIClient/Config.pm index 25ed56b..166a629 100644 --- a/PVE/APIClient/Config.pm +++ b/PVE/APIClient/Config.pm @@ -4,84 +4,42 @@ use strict; use warnings; use JSON; -use PVE::JSONSchema qw(register_standard_option get_standard_option); +use PVE::JSONSchema; use PVE::SectionConfig; use PVE::Tools qw(file_get_contents file_set_contents); use base qw(PVE::SectionConfig); +my $remote_namne_regex = qw(\w+); + +my $defaults_section = '!DEFAULTS'; + my $complete_remote_name = sub { my $config = PVE::APIClient::Config->load(); - return [keys %{$config->{ids}}]; + my $list = []; + foreach my $name (keys %{$config->{ids}}) { + push @$list, $name if $name ne $defaults_section; + } + return $list; }; -register_standard_option('pveclient-remote-name', { +PVE::JSONSchema::register_standard_option('pveclient-remote-name', { description => "The name of the remote.", type => 'string', - pattern => qr(\w+), + pattern => $remote_namne_regex, completion => $complete_remote_name, }); - my $defaultData = { propertyList => { type => { description => "Section type.", optional => 1, }, - 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 user's 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 type { - return 'remote'; -} - -sub options { - return { - name => { optional => 0 }, - host => { optional => 0 }, - comment => { optional => 1 }, - username => { optional => 0 }, - password => { optional => 1 }, - port => { optional => 1 }, - fingerprint => { optional => 1 }, - }; -} - sub private { return $defaultData; } @@ -96,6 +54,32 @@ sub config_filename { 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) = @_; @@ -119,11 +103,21 @@ 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) = @_; @@ -159,7 +153,98 @@ sub remote_conn { return $conn; } +package PVE::APIClient::RemoteConfig; + +use strict; +use warnings; + +use PVE::JSONSchema qw(register_standard_option get_standard_option); +use PVE::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::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(); -__PACKAGE__->init(); + + +PVE::APIClient::Config->init(); 1; diff --git a/pveclient b/pveclient index 52f40a7..f18dab9 100755 --- a/pveclient +++ b/pveclient @@ -12,6 +12,7 @@ use PVE::CLIHandler; use PVE::APIClient::LWP; use PVE::APIClient::Helpers; +use PVE::APIClient::Commands::config; use PVE::APIClient::Commands::remote; use PVE::APIClient::Commands::list; use PVE::APIClient::Commands::lxc; @@ -36,6 +37,7 @@ my $cli_class_handlers = { list => 'PVE::APIClient::Commands::list', lxc => 'PVE::APIClient::Commands::lxc', remote => 'PVE::APIClient::Commands::remote', + config => 'PVE::APIClient::Commands::config', help => 'PVE::APIClient::Commands::help', }; -- 2.39.2