use PVE::JSONSchema qw(get_standard_option);
use PVE::RESTHandler;
use PVE::INotify;
+use PVE::APIClient::LWP;
use PMG::ClusterConfig;
+use PMG::Cluster;
use base qw(PVE::RESTHandler);
+sub cluster_join {
+ my ($conn_setup) = @_;
+
+ my $conn = PVE::APIClient::LWP->new(%$conn_setup);
+
+ my $info = PMG::Cluster::read_local_cluster_info();
+
+ my $res = $conn->post("/config/cluster/nodes", $info);
+}
+
__PACKAGE__->register_method({
name => 'index',
path => '',
return PVE::RESTHandler::hash_to_array($cfg->{ids}, 'cid');
}});
+my $add_node_schema = PMG::ClusterConfig::Node->createSchema(1);
+delete $add_node_schema->{properties}->{cid};
+
+__PACKAGE__->register_method({
+ name => 'add_node',
+ path => 'nodes',
+ method => 'POST',
+ description => "Add an node to the cluster config.",
+ proxyto => 'master',
+ protected => 1,
+ parameters => $add_node_schema,
+ returns => { type => 'null' },
+ code => sub {
+ my ($param) = @_;
+
+ my $code = sub {
+ my $cfg = PMG::ClusterConfig->new();
+
+ die "no cluster defined\n" if !scalar(keys %{$cfg->{ids}});
+
+ my $master = $cfg->{master} || die "unable to lookup master node\n";
+
+ $master->{maxcid}++;
+
+ my $node = {
+ type => 'node',
+ cid => $master->{maxcid},
+ };
+
+ foreach my $k (qw(ip name hostrsapubkey rootrsapubkey fingerprint)) {
+ $node->{$k} = $param->{$k};
+ }
+
+ # fixme: test if IP or name already exists
+
+ $cfg->{ids}->{$node->{cid}} = $node;
+
+ $cfg->write();
+ };
+
+ PMG::ClusterConfig::lock_config($code, "create cluster failed");
+
+ return undef;
+ }});
+
__PACKAGE__->register_method({
name => 'create',
path => 'create',
type => 'string',
pattern => '^(:?[A-Z0-9][A-Z0-9]:){31}[A-Z0-9][A-Z0-9]$',
},
+ password => {
+ description => "Superuser password.",
+ type => 'string',
+ maxLength => 128,
+ },
},
},
returns => { type => 'null' },
die "cluster alreayd defined\n" if scalar(keys %{$cfg->{ids}});
- die "implement me";
+ my $setup = {
+ username => 'root@pam',
+ password => $param->{password},
+ cookie_name => 'PMGAuthCookie',
+ host => $param->{master_ip},
+ cached_fingerprints => {
+ $param->{fingerprint} => 1,
+ }
+ };
+
+ cluster_join($setup);
};
PMG::ClusterConfig::lock_config($code, "cluster join failed");
use strict;
use warnings;
use Data::Dumper;
+use Term::ReadLine;
+use JSON;
use PVE::SafeSyslog;
use PVE::Tools qw(extract_param);
my $master = $cfg->{master} ||
die "no master found\n";
- print "pmgcm join --master_ip $master->{ip} --fingerprint $master->{fingerprint}\n";
+ print "pmgcm join $master->{ip} --fingerprint $master->{fingerprint}\n";
} else {
die "no cluster defined\n";
return undef;
}});
+__PACKAGE__->register_method({
+ name => 'join',
+ path => 'join',
+ method => 'GET',
+ description => "Join a new node to an existing cluster.",
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ master_ip => {
+ description => "IP address.",
+ type => 'string', format => 'ip',
+ },
+ fingerprint => {
+ description => "SSL certificate fingerprint.",
+ type => 'string',
+ pattern => '^(:?[A-Z0-9][A-Z0-9]:){31}[A-Z0-9][A-Z0-9]$',
+ optional => 1,
+ },
+ },
+ },
+ returns => { type => 'null' },
+ code => sub {
+ my ($param) = @_;
+
+ my $code = sub {
+ my $cfg = PVE::INotify::read_file('cluster.conf');
+
+ die "cluster alreayd defined\n" if scalar(keys %{$cfg->{ids}});
+
+ my $term = new Term::ReadLine ('pmgcm');
+ my $attribs = $term->Attribs;
+ $attribs->{redisplay_function} = $attribs->{shadow_redisplay};
+ my $password = $term->readline('Enter password: ');
+
+ my $setup = {
+ username => 'root@pam',
+ password => $password,
+ cookie_name => 'PMGAuthCookie',
+ host => $param->{master_ip},
+ };
+ if ($param->{fingerprint}) {
+ $setup->{cached_fingerprints} = {
+ $param->{fingerprint} => 1,
+ };
+ } else {
+ # allow manual fingerprint verification
+ $setup->{manual_verification} = 1;
+ }
+
+ PMG::API2::Cluster::cluster_join($setup);
+ };
+
+ PMG::ClusterConfig::lock_config($code, "cluster join failed");
+
+ return undef;
+ }});
+
our $cmddef = {
nodes => [ 'PMG::API2::Cluster', 'nodes', [], {}, $format_nodelist],
create => [ 'PMG::API2::Cluster', 'create', []],
- join => [ 'PMG::API2::Cluster', 'join', ['master_ip', 'fingerprint']],
+ join => [ __PACKAGE__, 'join', ['master_ip']],
join_cmd => [ __PACKAGE__, 'join_cmd', []],
};